在seaborn tsplot中将图例移到图外
Posted
技术标签:
【中文标题】在seaborn tsplot中将图例移到图外【英文标题】:Move legend outside figure in seaborn tsplot 【发布时间】:2015-08-10 00:39:42 【问题描述】:我想使用seaborn.tsplot
创建一个时间序列图,就像在this example from tsplot
documentation 中一样,但是图例移到了右侧,在图之外。
根据seaborn's timeseries.py 中的第 339-340 行,seaborn.tsplot
目前似乎不允许直接控制图例放置:
if legend:
ax.legend(loc=0, title=legend_name)
是否有 matplotlib 解决方法? 我正在使用 seaborn 0.6-dev。
【问题讨论】:
我想如果你再次调用ax.legend
它会重新绘制它,而不是添加第二个。
这能回答你的问题吗? Move seaborn plot legend to a different position
这个answer的副本。
【参考方案1】:
确实,seaborn
到目前为止还不能很好地处理图例。您可以使用plt.legend()
直接通过matplotlib
控制图例属性,按照Matplotlib Legend Guide。
请注意,在 Seaborn 0.10.0 中,tsplot
已被删除,您可以使用 lineplot
而不是 tsplot
复制(如果您愿意,使用不同的估计值)图。
片段
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="darkgrid")
# Load the long-form example gammas dataset
gammas = sns.load_dataset("gammas")
# Plot the response with standard error
sns.lineplot(data=gammas, x="timepoint", y="BOLD signal", hue="ROI")
# Put the legend out of the figure
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
输出
【讨论】:
最后一行是解决方案。它也适用于我的条形图。 似乎bbox_to_anchor=(1.05, 1)
覆盖了loc=2
,所以你可以直接删除loc
。还是我错过了什么?
这放了两个图例
@JemshitIskenderov 你的 seaborn 和 matplotlib 版本是什么?
在某些情况下,将图例移到绘图之外需要添加“plt.tight_layout()”以完全包含图例。【参考方案2】:
Sergey 的回答对我使用 seaborn.tsplot
非常有用,但我无法让它为 seaborn.lmplot
工作,所以我更深入地研究并找到了另一个解决方案:
例子:
import seaborn as sns
import pandas as pd
# load data
df = pd.DataFrame.from_csv('mydata.csv')
# create with hue but without legend
g = sns.lmplot(x="x_data", y="y_data", hue="condition", legend=False, data=df)
# resize figure box to -> put the legend out of the figure
box = g.ax.get_position() # get position of figure
g.ax.set_position([box.x0, box.y0, box.width * 0.85, box.height]) # resize position
# Put a legend to the right side
g.ax.legend(loc='center right', bbox_to_anchor=(1.25, 0.5), ncol=1)
sns.plt.show(g)
也许您必须调整这些值以使其适合您的传奇。 如果您需要更多示例,This 的回答也会有所帮助。
【讨论】:
【参考方案3】:我尝试将 T.W. 的答案应用于 seaborn lineplot,但没有成功。对他的答案进行一些修改就可以了……以防有人像我一样寻找线图版本!
import seaborn as sns
import pandas as pd
# load data
df = sns.load_dataset("gammas")
# EDIT: I Needed to ad the fig
fig, ax1 = plt.subplots(1,1)
# EDIT:
# T.W.' answer said: "create with hue but without legend" <- # I needed to include it!
# So, removed: legend=False
g = sns.lineplot(x="timepoint", y="BOLD signal", hue="ROI", data=df, ax=ax1)
# EDIT:
# Removed 'ax' from T.W.'s answer here aswell:
box = g.get_position()
g.set_position([box.x0, box.y0, box.width * 0.85, box.height]) # resize position
# Put a legend to the right side
g.legend(loc='center right', bbox_to_anchor=(1.25, 0.5), ncol=1)
plt.show()
【讨论】:
如果您在plt.show()
之前调用plt.tight_layout()
,则无需移动绘图。此外,g.legend(loc='center left', bbox_to_anchor=(1.02, 0.5), ncol=1)
会将图例放在右侧,并锚定其左侧中心。【参考方案4】:
纯seaborn
解决方案:
FacetGrid
-based Seaborn plots 可以使用legend_out
kwarg 自动执行此操作。使用relplot
,通过facet_kws
字典将legend_out
传递给FacetGrid
构造函数:
import seaborn as sns
sns.set(style="darkgrid")
gammas = sns.load_dataset("gammas")
sns.relplot(
data=gammas,
x="timepoint",
y="BOLD signal",
hue="ROI",
kind="line",
facet_kws="legend_out": True
)
【讨论】:
由于某种原因,facet_out=True
使用 seaborn 0.11.1
无效。
legend_out,不是 facet_out
我的意思是legend_out
。使用 seaborn 0.11.1 和 matplotlib 3.3.4。【参考方案5】:
现有的解决方案似乎通过使用“错误”的位置参数使事情变得不必要地复杂;想想传说与锚的关系。例如,如果你想要一个图例在右边,那么锚点位置就是它的center left
。
我们可以将 Sergey Antopolskiy 的回答简化为:
import seaborn as sns
# Load the long-form example gammas dataset
g = sns.lineplot(data=gammas, x="timepoint", y="BOLD signal", hue="ROI")
# Put the legend out of the figure
g.legend(loc='center left', bbox_to_anchor=(1, 0.5))
bbox_to_anchor
表示我们希望锚点位于右侧(即 x 轴上的 1
)和垂直居中(y 轴上的 0.5
)。 loc
说我们想要这个锚的左中角的图例。
在 Seaborn 0.11.0 版中,这给了我类似的信息:
【讨论】:
这很有帮助。谢谢! 这给了我一个'Legend' object is not callable
错误(seaborn 0.11.2)
@emilaz 认为您必须在做其他事情,它适用于 0.11.2
是的,我这样做是为了一个 seaborn pairplot,这可能是原因:)以上是关于在seaborn tsplot中将图例移到图外的主要内容,如果未能解决你的问题,请参考以下文章