Как вы можете редактировать несколько полей условных обозначений в точечной диаграмме шонборна?

#python #matplotlib #plot #seaborn #legend

Вопрос:

Я хочу переименовать и переместить две легенды. Я хочу, чтобы верхняя легенда была вне графика, вверху справа и озаглавлена 'Average Cost' . Я хочу, чтобы вторая легенда была вне графика, внизу справа и называлась 'Total Revenue'

 figure = plt.figure(figsize=(10,5))
ax = sns.scatterplot(
        x=top_rev_mean['cost_of_the_order_y'],
        y='cost_of_the_order_x', 
        data=top_rev_mean, 
        size = "cost_of_the_order_x", 
        hue='cost_of_the_order_y'
    )
plt.ylabel('Total Order Revenue')
plt.xlabel('Average Order Cost Per Cuisine')
plt.show()
 

Разброс Затрат

Ответ №1:

Я полагаю, вы работаете с таким фреймом данных, как этот:

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


N = 15
top_rev_mean = pd.DataFrame({'cost_of_the_order_y': 17.6   4*np.random.random(N),
                             'cost_of_the_order_x': 500   2000*np.random.random(N)})
 
     cost_of_the_order_y  cost_of_the_order_x
0             19.098160           866.809020
1             21.402857          1108.484486
2             20.527976          1549.512863
3             19.994634          1363.890037
4             18.224075          1082.458280
5             18.223978          1723.705789
6             17.832334           778.987721
7             21.064705          1084.289297
8             20.004460          1232.723687
9             20.432290          1412.139968
10            17.682338          2070.351923
11            21.479639           899.347564
12            20.929771          1528.468877
13            18.449356          1684.829138
14            18.327300           592.900825
 

Когда вы настраиваете диаграмму рассеяния, вы должны быть уверены, что легенда нарисована, чтобы позже получить маркеры и метки, поэтому вам нужно передать legend = True параметр в seaborn.scatterplot :

 fig, ax = plt.subplots(figsize=(10,5))

sns.scatterplot(ax = ax, data = top_rev_mean, x = 'cost_of_the_order_y', y = 'cost_of_the_order_x', size = "cost_of_the_order_x", hue = 'cost_of_the_order_y', legend = True)
 

Затем вы можете извлечь дескрипторы и метки текущей легенды с помощью ax.get_legend_handles_labels :

 handles, labels = ax.get_legend_handles_labels()
 

Теперь вам нужно разделить элементы первой легенды от элементов второй:

 legend1 = {}
legend2 = {}
titles = {}

for handle, label in zip(handles, labels):
    if label.replace('.', '').isdigit() == False:
        titles[handle] = label
    else:
        if len(list(titles.keys())) == 1:
            legend1[handle] = label
        else:
            legend2[handle] = label
 

Наконец, вы можете удалить легенду, нарисованную из сиборна, и нарисовать две легенды, которые вы хотите:

 ax.legend().remove()

upper_legend = ax.legend(handles = list(legend1.keys()), labels = list(legend1.values()), title = 'Average Cost', loc = 'upper left', bbox_to_anchor = (1.05, 1))
ax.add_artist(upper_legend)
lower_legend = ax.legend(handles = list(legend2.keys()), labels = list(legend2.values()), title = 'Total Revenue', loc = 'lower left', bbox_to_anchor = (1.05, 0))
 

Полный Код

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


N = 15
top_rev_mean = pd.DataFrame({'cost_of_the_order_y': 17.6   4*np.random.random(N),
                             'cost_of_the_order_x': 500   2000*np.random.random(N)})


fig, ax = plt.subplots(figsize=(10,5))

sns.scatterplot(ax = ax, data = top_rev_mean, x = 'cost_of_the_order_y', y = 'cost_of_the_order_x', size = "cost_of_the_order_x", hue = 'cost_of_the_order_y', legend = True)

handles, labels = ax.get_legend_handles_labels()

legend1 = {}
legend2 = {}
titles = {}

for handle, label in zip(handles, labels):
    if label.replace('.', '').isdigit() == False:
        titles[handle] = label
    else:
        if len(list(titles.keys())) == 1:
            legend1[handle] = label
        else:
            legend2[handle] = label


ax.legend().remove()

upper_legend = ax.legend(handles = list(legend1.keys()), labels = list(legend1.values()), title = 'Average Cost', loc = 'upper left', bbox_to_anchor = (1.05, 1))
ax.add_artist(upper_legend)
lower_legend = ax.legend(handles = list(legend2.keys()), labels = list(legend2.values()), title = 'Total Revenue', loc = 'lower left', bbox_to_anchor = (1.05, 0))

ax.set_ylabel('Total Order Revenue')
ax.set_xlabel('Average Order Cost Per Cuisine')

plt.tight_layout()

plt.show()
 

введите описание изображения здесь

Комментарии:

1. Это прекрасно. Спасибо!