Seaborn 和 matplotlib 控制子图中的图例

My *_*ork 4 python matplotlib legend subplot seaborn

我一直在玩 plt.legend() 和 ax.legend() 以及来自seaborn本身的图例,我想我错过了一些东西。

我的第一个问题是,有人可以向我解释一下它们是如何结合在一起的,它们是如何工作的,如果我有次要情节,什么比什么更好?意思是我可以设置一个一般定义(例如,在此位置的所有子图中都有这个图例),然后为特定子图覆盖这个定义(例如通过 ax.legend() )?

我的第二个问题很实际,也展示了我的问题。我们以seaborn Smokers数据集来说明一下:

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

# define sizes for labels, ticks, text, ...
# as defined here /sf/ask/272998631/
SMALL_SIZE = 10
MEDIUM_SIZE = 14
BIGGER_SIZE = 18

plt.rc('font', size=SMALL_SIZE)          # controls default text sizes
plt.rc('axes', titlesize=SMALL_SIZE)     # fontsize of the axes title
plt.rc('axes', labelsize=BIGGER_SIZE)    # fontsize of the x and y labels
plt.rc('xtick', labelsize=MEDIUM_SIZE)    # fontsize of the tick labels
plt.rc('ytick', labelsize=MEDIUM_SIZE)    # fontsize of the tick labels
plt.rc('legend', fontsize=SMALL_SIZE)    # legend fontsize
plt.rc('figure', titlesize=BIGGER_SIZE)  # fontsize of the figure title


# create figure
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize=(16,12))
ylim = (0,1)

sns.boxplot(x= 'day', y= 'tip', hue="sex",
                  data=tips, palette="Set2", ax=ax1)
sns.swarmplot(x= 'day', y= 'tip', hue="sex",
                  data=tips, palette="Set2", ax=ax2)
ax2.legend(loc='upper right')

sns.boxplot(x= 'day', y= 'total_bill', hue="sex",
                  data=tips, palette="Set2", ax=ax3)
sns.swarmplot(x= 'day', y= 'total_bill', hue="sex",
                  data=tips, palette="Set2", ax=ax4)


plt.suptitle('Smokers')
plt.legend(loc='upper right')

plt.savefig('test.png', dpi = 150)
Run Code Online (Sandbox Code Playgroud)

情节示例。

如果我简单地使用seaborn,我会得到一个如子图1和3中的图例——它有“hue”标签并遵循定义的字体大小。但是,我无法控制它的位置(它有一些默认值,请参阅 1 和 3 之间的区别)。如果我像子图 2 中那样使用 ax.legend() ,那么我可以修改特定的子图,但我失去了 seaborn 'hue' 功能(请注意,“性别”消失了),并且它不遵循我的字体定义。如果我使用 plt.legend(),它只会影响之前的子图(在本例中为子图 4)。我怎样才能把这一切结合起来?例如。对所有子图都有一个定义或如何控制seaborn默认值?为了明确目标,如何像子图 1 中那样有一个图例,其中标签自动来自数据(但我可以更改它们),并且所有子图的位置、字体大小等设置相同(例如,右上角,字体大小为 10,...)?

感谢您的帮助和解释。

Imp*_*est 6

Seaborn legend 总是用关键字来调用loc=best。这是硬编码在源代码中的。您可以更改源代码,例如在这一行中并替换为ax.legend(). 然后在代码中设置 rc 参数,例如

plt.rc('legend', loc="upper right")
Run Code Online (Sandbox Code Playgroud)

将给出所需的输出。

唯一的其他选择是手动创建图例,就像在第二种情况下所做的那样,

ax2.legend(loc="upper right", title="sex", title_fontsize="x-large")
Run Code Online (Sandbox Code Playgroud)