【问题标题】:Save a subplot in matplotlib在 matplotlib 中保存子图
【发布时间】:2011-05-18 13:34:06
【问题描述】:

是否可以在 matplotlib 图形中保存(到 png)单个子图?假设我有

import pyplot.matplotlib as plt
ax1 = plt.subplot(121)
ax2 = plt.subplot(122)
ax1.plot([1,2,3],[4,5,6])    
ax2.plot([3,4,5],[7,8,9])

是否可以将两个子图中的每一个保存到不同的文件中,或者至少将它们分别复制到一个新图形中以保存它们?

我在 RHEL 5 上使用 1.0.0 版的 matplotlib。

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    虽然@Eli 非常正确,通常不需要这样做,但这是可能的。 savefig 采用 bbox_inches 参数,可用于选择性地仅将图形的一部分保存到图像中。

    这是一个简单的例子:

    import matplotlib.pyplot as plt
    import matplotlib as mpl
    import numpy as np
    
    # Make an example plot with two subplots...
    fig = plt.figure()
    ax1 = fig.add_subplot(2,1,1)
    ax1.plot(range(10), 'b-')
    
    ax2 = fig.add_subplot(2,1,2)
    ax2.plot(range(20), 'r^')
    
    # Save the full figure...
    fig.savefig('full_figure.png')
    
    # Save just the portion _inside_ the second axis's boundaries
    extent = ax2.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
    fig.savefig('ax2_figure.png', bbox_inches=extent)
    
    # Pad the saved area by 10% in the x-direction and 20% in the y-direction
    fig.savefig('ax2_figure_expanded.png', bbox_inches=extent.expanded(1.1, 1.2))
    

    全图:


    区域 inside 第二个子图:


    第二个子图周围的区域在 x 方向上填充 10%,在 y 方向上填充 20%:

    【讨论】:

    • +1:哇!我希望我在尝试了解有关 Matplotlib 的更多信息时遇到了这些方法!如果官方文档将感兴趣的读者引导到 Matplotlib 的这些有用的角落,并且相关概念的介绍更加结构化,那就太好了。 :)
    • 非常感谢,这正是我想要的!
    • 没有学到新东西的一天是糟糕的一天...干得好 ++
    • 如果我们使用extent.expanded()方法,如何减少生成的图形顶部和右侧的冗余空间?我们可以精确地指定农产品图形四个侧面的空间吗?那太好了。
    • 神奇。我不知道你想通了。
    【解决方案2】:

    在@Joe 3 年后从here 的答案中应用full_extent() 函数,您可以得到 OP 正在寻找的确切内容。或者,您可以使用Axes.get_tightbbox() 提供更紧密的边界框

    import matplotlib.pyplot as plt
    import matplotlib as mpl
    import numpy as np
    from matplotlib.transforms import Bbox
    
    def full_extent(ax, pad=0.0):
        """Get the full extent of an axes, including axes labels, tick labels, and
        titles."""
        # For text objects, we need to draw the figure first, otherwise the extents
        # are undefined.
        ax.figure.canvas.draw()
        items = ax.get_xticklabels() + ax.get_yticklabels() 
    #    items += [ax, ax.title, ax.xaxis.label, ax.yaxis.label]
        items += [ax, ax.title]
        bbox = Bbox.union([item.get_window_extent() for item in items])
    
        return bbox.expanded(1.0 + pad, 1.0 + pad)
    
    # Make an example plot with two subplots...
    fig = plt.figure()
    ax1 = fig.add_subplot(2,1,1)
    ax1.plot(range(10), 'b-')
    
    ax2 = fig.add_subplot(2,1,2)
    ax2.plot(range(20), 'r^')
    
    # Save the full figure...
    fig.savefig('full_figure.png')
    
    # Save just the portion _inside_ the second axis's boundaries
    extent = full_extent(ax2).transformed(fig.dpi_scale_trans.inverted())
    # Alternatively,
    # extent = ax.get_tightbbox(fig.canvas.renderer).transformed(fig.dpi_scale_trans.inverted())
    fig.savefig('ax2_figure.png', bbox_inches=extent)
    

    我会发布一张照片,但我缺乏声誉点

    【讨论】:

    • 可以通过添加项目 += [ax.get_xaxis().get_label(), ax.get_yaxis().get_label()] 扩展此答案以包含文本标签。在我添加之前,它们被切断了。
    猜你喜欢
    • 2018-12-27
    • 1970-01-01
    • 2018-06-06
    • 2019-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    相关资源
    最近更新 更多