Разделяй легенду о морских обитателях на две отдельные коробки - PullRequest
0 голосов
/ 05 июня 2019

Я использую Seaborn для генерации многих типов графиков, но здесь я буду использовать простой пример для иллюстрации на основе включенного набора данных:

import seaborn
tips = seaborn.load_dataset("tips")
axes = seaborn.scatterplot(x="day", y="tip", size="sex", hue="time", data=tips)

enter image description here

В этом результате один блок легенд содержит два заголовка «время» и «пол», каждый с подэлементами.

Как можно легко разделить легенду на два блока, каждый содин заголовок?Т.е. один для блока легенды, указывающий цветовые коды (который может быть размещен слева), и один блок легенды, указывающий коды размера (который будет помещен справа).

Ответы [ 3 ]

2 голосов
/ 05 июня 2019

Следующий код работает хорошо, потому что есть такое же количество временных категорий, что и категории пола. Если это не обязательно так, вам придется рассчитать a priori , сколько строк легенды требуется для каждой "метки"

fig = plt.figure()
tips = seaborn.load_dataset("tips")
axes = seaborn.scatterplot(x="day", y="tip", size="sex", hue="time", data=tips)
h,l = axes.get_legend_handles_labels()
l1 = axes.legend(h[:int(len(h)/2)],l[:int(len(l)/2)], loc='upper left')
l2 = axes.legend(h[int(len(h)/2):],l[int(len(l)/2):], loc='upper right')
axes.add_artist(l1) # we need this because the 2nd call to legend() erases the first

output graph

1 голос
/ 05 июня 2019

Если вы хотите использовать matplotlib вместо seaborn,

import matplotlib.pyplot as plt
import seaborn
tips = seaborn.load_dataset("tips")

tips["time_int"] = tips["time"].cat.codes
tips["sex_int"] = (tips["sex"].cat.codes*5+5)**2

sc = plt.scatter(x="day", y="tip", s="sex_int", c="time_int", data = tips, cmap="bwr")

leg1 = plt.legend(sc.legend_elements("colors")[0], tips["time"].cat.categories,
                  title="Time", loc="upper right")
leg2 = plt.legend(sc.legend_elements("sizes")[0], tips["sex"].cat.categories,
                  title="Sex", loc="upper left")
plt.gca().add_artist(leg1)
plt.show()

enter image description here

0 голосов
/ 06 июня 2019

Я взял Ответ Дизиета и расширил его.Он создал необходимый синтаксис, который мне был нужен, но, как он указал, не нашел способа подсчитать, сколько строк легенды требуется для разделения легенды.Я добавил это и написал полный сценарий:

# Modules #
import seaborn
from matplotlib import pyplot

# Plot #
tips = seaborn.load_dataset("tips")
axes = seaborn.scatterplot(x="day", y="tip", size="sex", hue="time", data=tips)

# Legend split and place outside #
num_of_colors   = len(tips['time'].unique()) + 1
handles, labels = axes.get_legend_handles_labels()
color_hl = handles[:num_of_colors], labels[:num_of_colors]
sizes_hl = handles[num_of_colors:], labels[num_of_colors:]

# Call legend twice #
color_leg = axes.legend(*color_hl,
                        bbox_to_anchor = (1.05, 1),
                        loc            = 'upper left',
                        borderaxespad  = 0.)
sizes_leg = axes.legend(*sizes_hl,
                        bbox_to_anchor = (1.05, 0),
                        loc            = 'lower left',
                        borderaxespad  = 0.)

# We need this because the 2nd call to legend() erases the first #
axes.add_artist(color_leg)

# Adjust #
pyplot.subplots_adjust(right=0.75)

# Display #
pyplot.ion()
pyplot.show()

enter image description here

...