此刻,我正在学习如何使用matplotlib
和seaborn
,其背后的概念对我来说似乎很陌生。人们会期望sns.countplot
函数返回一个具有.plot()
和.save()
功能的对象,因此可以在另一函数中使用绘图。
相反,似乎每次对sns.countplot
的调用都会覆盖先前的对象(请参见MWE)。
一方面,如果有人可以提供matplotlib
和seaborn
接口的说明(或链接了一些很好的Doku),将不胜感激。由于我阅读的所有Doku都没有太大帮助。
另一方面,我有一个返回一些图表的函数,我想将其另存为.pdf
文件,每页一个图表。我发现了类似的question,但是无法以使我的MWE正常运行的方式来复制代码。
from matplotlib.backends.backend_pdf import PdfPages
import seaborn as sns
def generate_plots():
penguins = sns.load_dataset("penguins")
countplot_sex = sns.countplot(y='sex', data=penguins)
countplot_species = sns.countplot(y='species', data=penguins)
countplot_island = sns.countplot(y='island', data=penguins)
# As showes
# print(countplot_sex) -> AxesSubplot(0.125,0.11;0.775x0.77)
# print(countplot_species) -> AxesSubplot(0.125,0.11;0.775x0.77)
# print(countplot_island) -> AxesSubplot(0.125,0.11;0.775x0.77)
# All three variables contain the same object
return(countplot_sex, countplot_species, countplot_island)
def plots2pdf(plots, fname): # from: https://stackoverflow.com/a/21489936
pp = PdfPages('multipage.pdf')
for plot in plots:
pass
# TODO save plot
# Does not work: plot.savefig(pp, format='pdf')
pp.savefig()
pp.close()
def main():
plots2pdf(generate_plots(), 'multipage.pdf')
if __name__ == '__main__':
main()
我的想法是拥有一个相当不错的软件体系结构,其中一个函数生成绘图,而另一个函数保存它们。
答案 0 :(得分:1)
问题是默认情况下,sns.countplot
将在当前的matplotlib Axes实例上进行绘制。来自docs:
ax
matplotlib轴,可选将绘图绘制到的轴对象,否则使用当前轴。
一种解决方案是定义一个小函数,该函数创建一个新的图形和Axes实例,然后将其传递给sns.countplot
,以确保将其绘制在新图形上并且不会覆盖前一个图形。这是我在下面的示例中显示的内容。一种替代方法是只创建3个图形和轴,然后将每个图形和轴自己传递给sns.countplot
函数。
然后在plots2pdf
函数中,可以遍历轴,并在保存时将其图形实例传递到PdfPages
实例。 (注意:由于您是在generate_plots
函数中创建图形的,因此另一种方法是从该函数返回图形实例,然后让它们准备好传递到pp.savefig
函数中,但是我做到了这样,您的函数输出将保持不变)。
from matplotlib.backends.backend_pdf import PdfPages
import seaborn as sns
import matplotlib.pyplot as plt
def generate_plots():
penguins = sns.load_dataset("penguins")
def my_countplot(y, data):
fig, ax = plt.subplots()
sns.countplot(y=y, data=data)
return ax
countplot_sex = my_countplot(y='sex', data=penguins)
countplot_species = my_countplot(y='species', data=penguins)
countplot_island = my_countplot(y='island', data=penguins)
return(countplot_sex, countplot_species, countplot_island)
def plots2pdf(plots, fname):
with PdfPages(fname) as pp:
for plot in plots:
pp.savefig(plot.figure)
def main():
plots2pdf(generate_plots(), 'multipage.pdf')
if __name__ == '__main__':
main()
生成的多页pdf的屏幕截图: