将多个海洋图保存到一个pdf文件中

时间:2020-10-09 09:47:45

标签: python matplotlib pdf save seaborn

此刻,我正在学习如何使用matplotlibseaborn,其背后的概念对我来说似乎很陌生。人们会期望sns.countplot函数返回一个具有.plot().save()功能的对象,因此可以在另一函数中使用绘图。 相反,似乎每次对sns.countplot的调用都会覆盖先前的对象(请参见MWE)。

一方面,如果有人可以提供matplotlibseaborn接口的说明(或链接了一些很好的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()

我的想法是拥有一个相当不错的软件体系结构,其中一个函数生成绘图,而另一个函数保存它们。

1 个答案:

答案 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的屏幕截图:

enter image description here