web-dev-qa-db-ja.com

Seaborn boxplot + stripplot:凡例の重複

seabornで簡単に作成できる最も優れた機能の1つは、boxplot + stripplotの組み合わせです。

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

tips = sns.load_dataset("tips")

sns.stripplot(x="day", y="total_bill", hue="smoker",
data=tips, jitter=True,
palette="Set2", split=True,linewidth=1,edgecolor='gray')

sns.boxplot(x="day", y="total_bill", hue="smoker",
data=tips,palette="Set2",fliersize=0)

plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.);

boxplot+stripplot

残念ながら、上記のように、ボックスプロット用とストリッププロット用の2つの凡例が生成されました。明らかに、それはばかげて冗長です。しかし、stripplotの凡例を取り除き、boxplotの凡例だけを残す方法を見つけることができないようです。おそらく、何とかplt.legendから項目を削除できますが、ドキュメントでは見つかりません。

28

凡例自体を実際に描画する前に、凡例で ハンドル/ラベルが存在する必要があるものを取得 できます。次に、必要な特定のものだけで凡例を描画します。

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

tips = sns.load_dataset("tips")

sns.stripplot(x="day", y="total_bill", hue="smoker",
data=tips, jitter=True,
palette="Set2", split=True,linewidth=1,edgecolor='gray')

# Get the ax object to use later.
ax = sns.boxplot(x="day", y="total_bill", hue="smoker",
data=tips,palette="Set2",fliersize=0)

# Get the handles and labels. For this example it'll be 2 tuples
# of length 4 each.
handles, labels = ax.get_legend_handles_labels()

# When creating the legend, only use the first two elements
# to effectively remove the last two.
l = plt.legend(handles[0:2], labels[0:2], bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)

example plot

26
Ffisegydd

サブプロットを使用する場合、凡例の処理が少し問題になる可能性があることを付け加えておきます。ちなみに(@Sergey Antopolskiyおよび@Ffisegydd)非常に素晴らしい図を与える上記のコードは、サブプロット内の凡例を再配置せず、非常に頑固に表示され続けます。サブプロットに適合した上記のコードを参照してください:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

tips = sns.load_dataset("tips")

fig, axes = sns.plt.subplots(2,2)

sns.stripplot(x="day", y="total_bill", hue="smoker",
              data=tips, jitter=True, palette="Set2", 
              split=True,linewidth=1,edgecolor='gray', ax = axes[0,0])

ax = sns.boxplot(x="day", y="total_bill", hue="smoker",
                 data=tips,palette="Set2",fliersize=0, ax = axes[0,0])

handles, labels = ax.get_legend_handles_labels()

l = plt.legend(handles[0:2], labels[0:2], bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)

duplicated legend

元の伝説は残っています。それを消去するには、次の行を追加します。

axes[0,0].legend(handles[:0], labels[:0])

corrected legend

編集:Seabornの最近のバージョン(> 0.9.0)では、コメントに指摘されているように、これは隅に小さな白いボックスを残していました。それを解決するには この投稿の答え を使用します:

axes[0,0].get_legend().remove()
5
BossaNova