为多个kde绘图创建一个图例

2024-09-24 22:18:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用python制作一个图表,我希望所有子情节都有一个图例。我遇到了问题,因为在我的绘图中,我无法使用获取\u legend\u handles\u labels(),因为它给我带来了实现目标的问题

我附上代码和图像,看看你是否能帮助我

多谢各位

    figure, axes = plt.subplots(1, 4, sharex=True, figsize=(16,4))
    
    sns.set(style="darkgrid")
    df = pd.concat(axis=0, ignore_index=True, objs=[
        pd.DataFrame.from_dict({'FYA': preds_full, '': 'original data'}),
        pd.DataFrame.from_dict({'FYA': preds_full_c, '': 'modified_data'})
    ])
    df1 = pd.concat(axis=0, ignore_index=True, objs=[
        pd.DataFrame.from_dict({'FYA': preds_full_c, '': 'original data'}),
        pd.DataFrame.from_dict({'FYA': preds_full_c, '': 'modified_data'})
    ])
    sns.kdeplot(ax=axes[0], data=df, x='FYA', hue='', fill=True, palette=['skyblue','lightcoral'], legend=False).set(title='black<-->white') 
    g, = sns.kdeplot(ax=axes[3], data=df1, x='FYA', hue='', fill=True, palette=['skyblue','lightcoral'], legend=True).set(title='asian<-->white')
    plt.setp(axes[3], ylabel='')

    handles, labels = axes.get_legend_handles_labels()
    figure.legend(handles, labels, loc='upper right', ncol=3, bbox_to_anchor=(.75, 0.98))   

    #plt.setp(axes[-1, :], xlabel='FYA')
    #plt.setp(axes[:, 0], ylabel='Density')
    plt.show()

enter image description here


Tags: fromtruedataframedatalabelspltdicthandles
1条回答
网友
1楼 · 发布于 2024-09-24 22:18:15

使用新的^{}函数,可以一次性创建子地块。作为输入,需要一个组合的数据帧,将单独的数据帧连接起来。col=关键字指示哪个数据帧列将启动新的子批。您可能需要检查^{} documentation以查找其他关键字(例如common_norm=multiple=

注意displot是一个figure-level function,它创建自己的图形,并根据子地块的数量以及height=aspect=关键字设置figsize

以下是一个例子:

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

sns.set(style="darkgrid")
df = pd.concat(axis=0, ignore_index=True, objs=[
    pd.DataFrame.from_dict({'FYA': np.random.randn(20), '': 'original data'}),
    pd.DataFrame.from_dict({'FYA': np.random.randn(15), '': 'modified_data'})])
df1 = pd.concat(axis=0, ignore_index=True, objs=[
    pd.DataFrame.from_dict({'FYA': np.random.randn(22), '': 'original data'}),
    pd.DataFrame.from_dict({'FYA': np.random.randn(25), '': 'modified_data'})])
df2 = pd.concat(axis=0, ignore_index=True, objs=[
    pd.DataFrame.from_dict({'FYA': np.random.randn(21), '': 'original data'}),
    pd.DataFrame.from_dict({'FYA': np.random.randn(28), '': 'modified_data'})])
df3 = pd.concat(axis=0, ignore_index=True, objs=[
    pd.DataFrame.from_dict({'FYA': np.random.randn(29), '': 'original data'}),
    pd.DataFrame.from_dict({'FYA': np.random.randn(17), '': 'modified_data'})])

combined_df = pd.concat({'black<->orange': df, 'red<->yellow': df1, 'green<->blue': df2, 'purple<->pink': df3})
combined_df = combined_df.reset_index(level=0).rename(columns={'level_0': 'subplot'}).reset_index()

g = sns.displot(kind='kde', data=combined_df, x='FYA', hue='', fill=True, col='subplot')
for ax, col_name in zip(g.axes.flat, g.col_names):
    ax.set_title(col_name)

plt.show()

sns.displot with kde

PS:如果出于某种原因,您希望更接近原始代码,那么可以使用sns.movelegend()。这是Seaborn 0.11.2中新增的,并更改了位置和其他图例属性。请注意,在matplotlib中,图例属于子地块(ax),而不是周围的图形。由于seaborn地块的复杂性,通常无法使用matplotlib的标准图例机制,需要创建自定义图例

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

preds_full = np.random.randn(20, 20).cumsum(axis=0).ravel()
preds_full_c = np.random.randn(20, 15).cumsum(axis=0).ravel()

figure, axes = plt.subplots(1, 4, sharex=True, sharey=True, figsize=(16, 4))

sns.set(style="darkgrid")
df = pd.concat(axis=0, ignore_index=True, objs=[
    pd.DataFrame.from_dict({'FYA': preds_full, '': 'original data'}),
    pd.DataFrame.from_dict({'FYA': preds_full_c, '': 'modified_data'})])
df1 = pd.concat(axis=0, ignore_index=True, objs=[
    pd.DataFrame.from_dict({'FYA': preds_full, '': 'original data'}),
    pd.DataFrame.from_dict({'FYA': preds_full_c, '': 'modified_data'})])
sns.kdeplot(ax=axes[0], data=df, x='FYA', hue='', fill=True, palette=['skyblue', 'lightcoral'], legend=False)
axes[0].set(title='black< >white')
sns.kdeplot(ax=axes[3], data=df1, x='FYA', hue='', fill=True, palette=['skyblue', 'lightcoral'], legend=True)
axes[3].set(title='asian< >white')
sns.move_legend(axes[3], loc='lower right', ncol=2, bbox_to_anchor=(1, 1.08))
plt.tight_layout()
plt.show()

moving a seaborn legend

相关问题 更多 >