【问题标题】:How to make savefig() save image for 'maximized' window instead of default size如何使 savefig() 为“最大化”窗口而不是默认大小保存图像
【发布时间】:2012-04-19 23:05:06
【问题描述】:

我在 matplotlib 中使用 pylab 来创建绘图并将绘图保存到图像文件中。但是,当我使用pylab.savefig( image_name )保存图像时,我发现保存的SIZE图像与我使用pylab.show()时显示的图像相同。

碰巧,我在图中有很多数据,当我使用pylab.show() 时,我必须最大化窗口才能正确看到所有图,并且 xlabel 代码不会叠加彼此。

在将图像保存到文件之前,我是否可以通过编程方式“最大化”窗口? - 目前,我只得到“默认”窗口大小的图像,这会导致 x 轴标签相互叠加。

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    您在初始化时设置大小:

    fig2 = matplotlib.pyplot.figure(figsize=(8.0, 5.0)) # in inches!
    

    编辑

    如果问题出在 x 轴刻度上 - 您可以“手动”设置它们:

    fig2.add_subplot(111).set_xticks(arange(1,3,0.5)) # You can actually compute the interval You need - and substitute here
    

    你情节的其他方面等等。您可以全部配置。这是一个例子:

    from numpy import arange
    import matplotlib
    # import matplotlib as mpl
    import matplotlib.pyplot
    # import matplotlib.pyplot as plt
    
    x1 = [1,2,3]
    y1 = [4,5,6]
    x2 = [1,2,3]
    y2 = [5,5,5]
    
    # initialization
    fig2 = matplotlib.pyplot.figure(figsize=(8.0, 5.0)) # The size of the figure is specified as (width, height) in inches
    
    # lines:
    l1 = fig2.add_subplot(111).plot(x1,y1, label=r"Text $formula$", "r-", lw=2)
    l2 = fig2.add_subplot(111).plot(x2,y2, label=r"$legend2$" ,"g--", lw=3)
    fig2.add_subplot(111).legend((l1,l2), loc=0)
    
    # axes:
    fig2.add_subplot(111).grid(True)
    fig2.add_subplot(111).set_xticks(arange(1,3,0.5))
    fig2.add_subplot(111).axis(xmin=3, xmax=6) # there're also ymin, ymax
    fig2.add_subplot(111).axis([0,4,3,6]) # all!
    fig2.add_subplot(111).set_xlim([0,4])
    fig2.add_subplot(111).set_ylim([3,6])
    
    # labels:
    fig2.add_subplot(111).set_xlabel(r"x $2^2$", fontsize=15, color = "r")
    fig2.add_subplot(111).set_ylabel(r"y $2^2$")
    fig2.add_subplot(111).set_title(r"title $6^4$")
    fig2.add_subplot(111).text(2, 5.5, r"an equation: $E=mc^2$", fontsize=15, color = "y")
    fig2.add_subplot(111).text(3, 2, unicode('f\374r', 'latin-1'))
    
    # saving:
    fig2.savefig("fig2.png")
    

    那么 - 你到底想配置什么?

    【讨论】:

    • 感谢您的及时回复。但是,这并不能解决问题。保存到文件的图像是调用pylab.show() 时显示的图像。对于我正在绘制的数据,我需要(手动)最大化窗口,以便在标签之间提供足够的间距。似乎在幕后,pylab.savefig() 正在执行pylab.show(),然后对 DEFAULT 大小的窗口进行屏幕截图并将其保存到文件中。我需要保存窗口最大化时显示的图像
    • 你为什么不自定义它所有的非 GUI 方式?我从来没有听说可以让 python 知道你在 pylab.show() 中所做的事情。
    • 继续...我只是想找到一种方法,在图像保存到文件之前“以编程方式”最大化“窗口”/画布(或至少指定特定大小)。跨度>
    • 答案实际上并没有回答问题。它可能会解决提问者的问题,但问题显然是如何保存最大化的数字 - 从这个答案中也不清楚。
    • @HomunculusReticulli 你有没有找到解决办法?我有同样的问题,所有建议的解决方案都没有解决保存问题。
    【解决方案2】:

    如果我正确理解您想要做什么,您可以创建您的图形并设置窗口的大小。之后,您可以使用 matplotlib 工具箱按钮保存您的图形。举个例子:

    from pylab import get_current_fig_manager,show,plt,imshow
    
    plt.Figure()
    thismanager = get_current_fig_manager()
    thismanager.window.wm_geometry("500x500+0+0") 
    #in this case 500 is the size (in pixel) of the figure window. In your case you want to maximise to the size of your screen or whatever
    
    imshow(your_data)
    show()
    

    【讨论】:

    • “您可以使用 matplotlib 工具箱按钮保存您的图表”——这正是我想要避免的完全。我想要一个自动化(即可编程)解决方案,而不是手动解决方案,因为我将在脚本中生成数百张图像。
    【解决方案3】:

    我认为在将图形保存到文件时需要指定不同的分辨率:

    fig = matplotlib.pyplot.figure()
    # generate your plot
    fig.savefig("myfig.png",dpi=600)
    

    指定较大的 dpi 值应该具有与最大化 GUI 窗口类似的效果。

    【讨论】:

    • 其实效果大不一样。增加 DPI 只会增加图像的分辨率,而改变图形的大小会改变子图、标题等之间的间距,而不会改变字体大小。所以需要先设置图形大小得到合适的字体大小,再设置DPI得到想要的分辨率。
    【解决方案4】:

    matplotlib(pylab)中有两个主要的选项来控制图片大小:

    1. 您可以以英寸为单位设置生成图像的大小
    2. 您可以为输出文件定义 DPI(每英寸点数)(基本上是分辨率)

    通常,您希望两者都做,因为这样您就可以完全控制生成的图像大小以像素为单位。例如,如果要精确渲染 800x600 的图像,可以使用 DPI=100,并将尺寸设置为 8 x 6 英寸:

    import matplotlib.pyplot as plt
    # plot whatever you need...
    # now, before saving to file:
    figure = plt.gcf() # get current figure
    figure.set_size_inches(8, 6)
    # when saving, specify the DPI
    plt.savefig("myplot.png", dpi = 100)
    

    可以使用任何 DPI。事实上,您可能想要使用各种 DPI 和大小值来获得您最喜欢的结果。但是请注意,使用非常小的 DPI 并不是一个好主意,因为 matplotlib 可能找不到合适的字体来渲染图例和其他文本。例如,您不能设置 DPI=1,因为没有以 1 像素呈现字符的字体:)

    从其他 cmets 我了解到您遇到的其他问题是正确的文本渲染。为此,您还可以更改字体大小。例如,您可以使用每个字符 6 个像素,而不是默认使用的每个字符 12 个像素(实际上,使所有文本变小两倍)。

    import matplotlib
    #...
    matplotlib.rc('font', size=6)
    

    最后,一些对原始文档的引用: http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.savefig, http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.gcf, http://matplotlib.sourceforge.net/api/figure_api.html#matplotlib.figure.Figure.set_size_inches, http://matplotlib.sourceforge.net/users/customizing.html#dynamic-rc-settings

    附:抱歉,我没有使用 pylab,但据我所知,以上所有代码在 pylab 中的工作方式相同 - 只需将我的代码中的 plt 替换为 pylab(或您在导入时指定的任何名称) pylab)。 matplotlib 相同 - 请改用 pylab

    【讨论】:

    • 刚刚尝试使用它。有些东西仍然减少了我的像素。我有一个 800 x 4000 像素的堆叠 numpy 图像数组,我想保存它而没有任何损失,这样我保存的图像正好是 800x4000 像素。使用了 figure(figsize=(8,40)) 和 savefig(fname, dpi=100) 并收到了 576x2880 像素的 PDF?
    • 我刚刚确认这是 PDF 引擎的问题。 png 正确输出。
    【解决方案5】:

    检查这个: How to maximize a plt.show() window using Python

    命令因您使用的后端而异。我发现这是确保保存的图片与我在屏幕上查看的图片具有相同缩放比例的最佳方式。

    由于我使用带有 QT 后端的 Canopy:

    pylab.get_current_fig_manager().window.showMaximized()
    

    然后我根据需要调用 savefig() 并根据 silvado 的回答增加 DPI。

    【讨论】:

    • 收到以下错误AttributeError: '_tkinter.tkapp' object has no attribute 'showMaximized'
    • @NagabhushanSN 听起来您可能正在使用不同的后端。最大化的方法会有所不同。
    • 哦!好的。谢谢!
    【解决方案6】:

    我之前也做过同样的搜索,看来他的确切解决方案取决于后端。

    我已经阅读了很多资料,其中最有用的可能是 Pythonio 的答案How to maximize a plt.show() window using Python 我调整了代码,最终得到了下面的函数。 它在 Windows 上工作得很好,我主要使用 Qt,我经常使用它,而它与其他后端的测试很少。

    基本上它包括识别后端和调用适当的函数。请注意,我后来添加了一个暂停,因为我遇到了一些窗口最大化而其他窗口没有最大化的问题,这似乎为我解决了。

    def maximize(backend=None,fullscreen=False):
        """Maximize window independently on backend.
        Fullscreen sets fullscreen mode, that is same as maximized, but it doesn't have title bar (press key F to toggle full screen mode)."""
        if backend is None:
            backend=matplotlib.get_backend()
        mng = plt.get_current_fig_manager()
    
        if fullscreen:
            mng.full_screen_toggle()
        else:
            if backend == 'wxAgg':
                mng.frame.Maximize(True)
            elif backend == 'Qt4Agg' or backend == 'Qt5Agg':
                mng.window.showMaximized()
            elif backend == 'TkAgg':
                mng.window.state('zoomed') #works fine on Windows!
            else:
                print ("Unrecognized backend: ",backend) #not tested on different backends (only Qt)
        plt.show()
    
        plt.pause(0.1) #this is needed to make sure following processing gets applied (e.g. tight_layout)
    

    【讨论】:

    【解决方案7】:

    您可以在保存的图形中查看它的大小,例如 1920x983 像素(我保存最大化窗口时的大小),然后我将 dpi 设置为 100,将大小设置为 19.20x9.83,效果很好。保存完全等于最大化的数字。

    import numpy as np
    import matplotlib.pyplot as plt
    x, y = np.genfromtxt('fname.dat', usecols=(0,1), unpack=True)
    a = plt.figure(figsize=(19.20,9.83))
    a = plt.plot(x, y, '-')
    plt.savefig('file.png',format='png',dpi=100)
    

    【讨论】:

      【解决方案8】:

      我遇到了这个确切的问题,这很有效:

      plt.savefig(output_dir + '/xyz.png', bbox_inches='tight')
      

      这是文档:

      [https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.savefig.html][1]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-02
        • 1970-01-01
        • 2019-05-11
        • 2012-07-24
        • 2015-07-21
        • 1970-01-01
        • 2022-01-17
        • 2019-02-25
        相关资源
        最近更新 更多