【问题标题】:Save multiple seaborn plots into one pdf file将多个 seaborn 绘图保存到一个 pdf 文件中
【发布时间】:2020-10-09 09:47:45
【问题描述】:

目前我正在学习如何使用matplotlibseaborn,它背后的概念对我来说似乎很奇怪。人们会期望sns.countplot 函数返回一个具有.plot().save() 函数的对象,因此可以在不同的函数中使用绘图。 相反,似乎每次调用 sns.countplot 都会覆盖之前的对象(请参阅 MWE)。

所以一方面如果有人可以提供matplotlibseaborn 接口的解释(或有一些好的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()

我的想法是有一个有点像样的软件架构,一个函数生成图,另一个函数保存它们。

【问题讨论】:

    标签: python matplotlib pdf save seaborn


    【解决方案1】:

    问题在于,默认情况下,sns.countplot 将在当前 matplotlib Axes 实例上进行绘图。来自docs

    ax matplotlib 轴,可选

    要在其上绘制绘图的 Axes 对象,否则使用当前 Axes。

    一种解决方案是定义一个小函数来创建一个新图形和 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截图:

    【讨论】:

    • 谢谢,因为除了 MWE 我还在使用其他 sns 函数,我将你的函数更改为:def myplot(func): _, axsis = plt.subplots(); func(); return(axsis) 我可以通过以下方式调用:myplot(lambda: sns.heatmap(. . .))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 2018-11-29
    • 2013-07-21
    • 1970-01-01
    相关资源
    最近更新 更多