提问者:小点点

海运配对图图例-如何控制位置


我想将Seaborn pairplot图例移到散点图矩阵之外。官方文档没有给出关键字图例。我试图同时在3个不同的位置绘制绘图外的图例:下中、上中、右中

我已经尝试过了:

import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset("iris")
g = sns.pairplot(iris,hue='species', palette='husl', markers='d', size=2.5, plot_kws=
    {
    "s":40,
    "alpha":1.0,
    'lw':0.5,
    'edgecolor':'k'
    })
plt.legend(loc='upper center', bbox_to_anchor=(1.10, 1.0), ncol=1) #vertical legend
plt.legend(loc='lower center', bbox_to_anchor=(0.0, -0.15), ncol=3) #horizontal legend bottom
plt.legend(loc='upper left', bbox_to_anchor=(0.0, 1.15), ncol=3) #horizontal legend top
g.savefig('Test.png', bbox_inches='tight')

所有3个图例打印不正确。我不确定它是否在做我要求的定位。我不确定右边发生了什么-似乎出现了两个垂直图例,出于某种原因,它们完全重叠。两个水平图例中的一个根本没有出现。

有没有一种方法可以避免垂直图例的重叠,并且将图例放在3个位置之外-顶部中心,底部中心,右侧中心?


共3个答案

匿名用户

pairplot已在绘图矩阵外添加图例,但不清楚要将其移动到何处。其他图例可能会按照您的要求进行定位,即使这可能不是您真正想要的。

plt.legend将向当前轴附加一个图例,并且每个轴只能有一个图例,因此在代码中只能绘制最后一个图例。但是你可以给一个图形附加几个图例,IIUC你想把图例相对于图形定位,这样图形图例看起来是最好的选择。

为了绘制图形图例,您需要显式地传递处理程序和标签。我必须使用私有属性PairPlot。_legend_data,我没有找到使用公共API的方法。

不幸的是,matplotlib不会自动腾出空间来修改这些图例,除非进行一些调整,否则它们将与子图重叠。在这种情况下,我将只使用subplot\u adjust和一些硬编码的值,因为计算很复杂。

这是一段代码,希望能满足您的需求:

g = sns.pairplot(iris, hue='species', palette='husl', markers='d', size=2.5, plot_kws=
    {
    "s":40,
    "alpha":1.0,
    'lw':0.5,
    'edgecolor':'k'
    })

handles = g._legend_data.values()
labels = g._legend_data.keys()
g.fig.legend(handles=handles, labels=labels, loc='upper center', ncol=1)
g.fig.legend(handles=handles, labels=labels, loc='lower center', ncol=3)
g.fig.legend(handles=handles, labels=labels, loc='upper left', ncol=3)
g.fig.subplots_adjust(top=0.92, bottom=0.08)

OP在评论中询问是否可以在seaborn文档中找到这一点。当然,这部分只是纯粹的matplotlib,而不是seaborn特有的。但我也意识到,我必须依赖一些未记录的特性。

事实上,PairGrid具有引用FIG实例的fig属性没有记录。不管怎样,这是一个简单的猜测,我可以用fig=plt.gcf()来代替。

获得传奇的标签和句柄更棘手。我通过查看PairGrid.add_legend的docstring了解了_legend_data属性,但是docstring本身有点隐藏(它不会出现在web中),并且属性被下划线,就像它是私密,所以用起来感觉不舒服。我发现在公共方法的文档字符串中提到私有属性是不一致的,也许我们应该将legend_data作为公共属性,但我跑题了。

或者,您可以尝试从子地块中提取标签和句柄。您可以猜到子地块有这些信息,但没有实际的担保,因此这意味着依赖于未记录的行为。事实证明,非对角子地块有它(但对角子地块没有,所以如果你只看第一个子地块,你会被误导),你可以做handles,labels=fig.get_axes()[1]。获取\u图例\u句柄\u标签()。但正如我所说的,这是未记录的行为,即使您只使用记录的API。

您也可以创建自己的句柄,但这会很麻烦,这就是为什么我寻找快捷方式,即使没有文档记录。

匿名用户

要控制默认对地块图例的位置,请执行以下操作:

    g._legend.set_bbox_to_anchor((0.5, 0.5))

匿名用户

这实际上比你想象的要容易得多。它只是在实际的矩阵图输出中的默认设置。只需转到输出窗口顶部的配置子图按钮,稍微降低右边框上限,它就会被修复。