停止 seaborn 在彼此之上绘制多个图形
Posted
技术标签:
【中文标题】停止 seaborn 在彼此之上绘制多个图形【英文标题】:Stop seaborn plotting multiple figures on top of one another 【发布时间】:2016-07-01 07:54:41 【问题描述】:我开始学习一点 Python(一直在使用 R)进行数据分析。我正在尝试使用seaborn
创建两个图,但它一直将第二个保存在第一个之上。如何阻止这种行为?
import seaborn as sns
iris = sns.load_dataset('iris')
length_plot = sns.barplot(x='sepal_length', y='species', data=iris).get_figure()
length_plot.savefig('ex1.pdf')
width_plot = sns.barplot(x='sepal_width', y='species', data=iris).get_figure()
width_plot.savefig('ex2.pdf')
【问题讨论】:
【参考方案1】:我同意之前的评论,即导入 matplotlib.pyplot
不是最好的软件工程实践,因为它暴露了底层库。当我在循环中创建和保存绘图时,我需要清除图形并发现现在可以通过仅导入 seaborn
轻松完成:
从 0.11 版开始:
import seaborn as sns
import numpy as np
data = np.random.normal(size=100)
path = "/path/to/img/plot.png"
plot = sns.displot(data) # also works with histplot() etc
plot.fig.savefig(path)
plot.fig.clf() # this clears the figure
# ... continue with next figure
带有循环的替代示例:
import seaborn as sns
import numpy as np
for i in range(3):
data = np.random.normal(size=100)
path = "/path/to/img/plot2_0:01d.png".format(i)
plot = sns.displot(data)
plot.fig.savefig(path)
plot.fig.clf() # this clears the figure
0.11 版之前(原帖):
import seaborn as sns
import numpy as np
data = np.random.normal(size=100)
path = "/path/to/img/plot.png"
plot = sns.distplot(data)
plot.get_figure().savefig(path)
plot.get_figure().clf() # this clears the figure
# ... continue with next figure
【讨论】:
这种方法在我在这里使用 seaborn 0.11.1 发表评论时不起作用 @RndmSymbl 实际上它仍然有效,但会引发很多关于 distplot() 的弃用警告,这可能会使用户感到困惑。我已经使用 displot() 和 histplot() 更新了使用新 API 的答案。另外,请注意,如果您使用一些 Python IDE,它只会显示最新的图 - 尽管会保存中间图。 虽然您答案中的代码确实有效。我发现避免数字相互重叠的唯一可靠方法是plt.figure()
调用。我有一个场景,我正在使用histplot()
、lineplot()
、boxplot()
和scatterplot()
的组合来绘制一系列PairGrid()
和FacetGrid()
。使用clf()
failed 来防止这个问题。【参考方案2】:
创建特定的图形并在其上绘制:
import seaborn as sns
iris = sns.load_dataset('iris')
length_fig, length_ax = plt.subplots()
sns.barplot(x='sepal_length', y='species', data=iris, ax=length_ax)
length_fig.savefig('ex1.pdf')
width_fig, width_ax = plt.subplots()
sns.barplot(x='sepal_width', y='species', data=iris, ax=width_ax)
width_fig.savefig('ex2.pdf')
【讨论】:
【参考方案3】:您必须开始一个新人物才能做到这一点。有多种方法可以做到这一点,假设你有matplotlib
。也摆脱get_figure()
,你可以从那里使用plt.savefig()
。
方法一
使用plt.clf()
import seaborn as sns
import matplotlib.pyplot as plt
iris = sns.load_dataset('iris')
length_plot = sns.barplot(x='sepal_length', y='species', data=iris)
plt.savefig('ex1.pdf')
plt.clf()
width_plot = sns.barplot(x='sepal_width', y='species', data=iris)
plt.savefig('ex2.pdf')
方法二
在每个人之前致电plt.figure()
plt.figure()
length_plot = sns.barplot(x='sepal_length', y='species', data=iris)
plt.savefig('ex1.pdf')
plt.figure()
width_plot = sns.barplot(x='sepal_width', y='species', data=iris)
plt.savefig('ex2.pdf')
【讨论】:
这个答案“有效”,但它不太喜欢 IMO,因为它依赖于 matplotlib 状态机接口,而不是完全接受面向对象的接口。快速绘图很好,但在某些时候,当复杂度扩大时,使用后者会更好。以上是关于停止 seaborn 在彼此之上绘制多个图形的主要内容,如果未能解决你的问题,请参考以下文章