Seaborn boxplot + stripplot: дублированная легенда
Одной из самых крутых вещей, которые вы можете легко сделать в seaborn
, является комбинация 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]()
К сожалению, как вы можете видеть выше, это создавало двойную легенду, одну для boxplot, одну для stripplot. Очевидно, это выглядит смешно и излишне. Но я не могу найти способ избавиться от легенды stripplot
и оставить легенду boxplot
. Вероятно, я могу как-то удалить элементы из plt.legend
, но я не могу найти его в документации.
Ответы
Ответ 1
Вы можете получить, какие дескрипторы/метки должны существовать в легенде, прежде чем вы на самом деле рисуете легенду. Затем вы рисуете легенду только с теми, которые вы хотите.
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]()
Ответ 2
Я хочу добавить, что если вы используете подсюжеты, обработка легенды может быть немного более проблематичной. Приведенный выше код, который, кстати, дает очень хорошую цифру (@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()