Seaborn 和 matplotlib 控制子图中的图例
Seaborn and matplotlib control legend in subplots
我一直在玩 plt.legend() 和 ax.legend() 以及 seaborn 本身的传说,我想我错过了一些东西。
我的第一个问题是,有人可以向我解释一下这些是如何结合在一起的,它们是如何工作的,如果我有子图,什么比什么更好?意思是我可以设置一个通用定义(例如,在这个 loc 的所有子图中都有这个图例),然后为特定的子图覆盖这个定义(例如 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
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)
如果我简单地使用 seaborn,我会得到一个如子图 1 和 3 中的图例——它有 'hue' 标签并遵循定义的字体大小。但是,我无法控制它的位置(它有一些默认值,请参见 1 和 3 之间的区别)。如果我在子图 2 中使用 ax.legend(),那么我可以修改特定的子图,但我失去了 seaborn 'hue' 功能(注意 "sex" 消失了)并且它不符合我的字体定义。如果我使用 plt.legend(),它只会影响它之前的子图(在本例中为子图 4)。
我怎样才能统一这一切?例如。对所有子图有一个定义或如何控制 seaborn 默认值?为了明确目标,如何在 Subplot 1 中创建一个图例,其中标签自动来自数据(但我可以更改它们)并且位置,字体大小......为所有子图设置相同(例如。右上角,字体大小为 10,...)?
感谢您的帮助和解释。
Seaborn 传奇始终使用关键字 loc=best
调用。这是在源代码中硬编码的。您可以更改源代码,例如in this line 并替换为 ax.legend()
。然后在代码中设置 rc 参数,如
plt.rc('legend', loc="upper right")
将给出所需的输出。
唯一的其他选择是手动创建图例,就像您在第二种情况下所做的那样,
ax2.legend(loc="upper right", title="sex", title_fontsize="x-large")
我一直在玩 plt.legend() 和 ax.legend() 以及 seaborn 本身的传说,我想我错过了一些东西。
我的第一个问题是,有人可以向我解释一下这些是如何结合在一起的,它们是如何工作的,如果我有子图,什么比什么更好?意思是我可以设置一个通用定义(例如,在这个 loc 的所有子图中都有这个图例),然后为特定的子图覆盖这个定义(例如 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
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)
如果我简单地使用 seaborn,我会得到一个如子图 1 和 3 中的图例——它有 'hue' 标签并遵循定义的字体大小。但是,我无法控制它的位置(它有一些默认值,请参见 1 和 3 之间的区别)。如果我在子图 2 中使用 ax.legend(),那么我可以修改特定的子图,但我失去了 seaborn 'hue' 功能(注意 "sex" 消失了)并且它不符合我的字体定义。如果我使用 plt.legend(),它只会影响它之前的子图(在本例中为子图 4)。 我怎样才能统一这一切?例如。对所有子图有一个定义或如何控制 seaborn 默认值?为了明确目标,如何在 Subplot 1 中创建一个图例,其中标签自动来自数据(但我可以更改它们)并且位置,字体大小......为所有子图设置相同(例如。右上角,字体大小为 10,...)?
感谢您的帮助和解释。
Seaborn 传奇始终使用关键字 loc=best
调用。这是在源代码中硬编码的。您可以更改源代码,例如in this line 并替换为 ax.legend()
。然后在代码中设置 rc 参数,如
plt.rc('legend', loc="upper right")
将给出所需的输出。
唯一的其他选择是手动创建图例,就像您在第二种情况下所做的那样,
ax2.legend(loc="upper right", title="sex", title_fontsize="x-large")