如何在 seaborn 散点图中编辑多个图例框?

Posted

技术标签:

【中文标题】如何在 seaborn 散点图中编辑多个图例框?【英文标题】:How can you edit multiple legend boxes in a seanborn scatter plot? 【发布时间】:2021-10-28 18:12:52 【问题描述】:

我想重命名和移动这两个图例。我希望顶部图例位于图表之外,右上角,标题为'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

最后可以去掉seaborn绘制的图例,画出你想要的两个图例:

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()

【讨论】:

这是完美的。谢谢!

以上是关于如何在 seaborn 散点图中编辑多个图例框?的主要内容,如果未能解决你的问题,请参考以下文章

更改 sns 散点图中的图例

如何在python的散点图中添加具有不同标记的多个图例?

如何为图形级功能编辑 seaborn 图例标题和标签

如何删除图例的特定部分(seaborn,散点图)

来自 pandas 数据框的散点图中的 Matplotlib 图例

在 seaborn 散点图中对分类 x 轴进行排序