将绘图保存到图像文件中,而不是使用Matplotlib显示它

时间:2022-10-31 10:15:58

I am writing a quick-and-dirty script to generate plots on the fly. I am using the code below (from Matplotlib documentation) as a starting point:

我正在编写一个快速而肮脏的脚本,以动态地生成情节。我使用下面的代码(来自Matplotlib文档)作为起点:

from pylab import figure, axes, pie, title, show

# Make a square figure and axes
figure(1, figsize=(6, 6))
ax = axes([0.1, 0.1, 0.8, 0.8])

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15, 30, 45, 10]

explode = (0, 0.05, 0, 0)
pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True)
title('Raining Hogs and Dogs', bbox={'facecolor': '0.8', 'pad': 5})

show()  # Actually, don't show, just save to foo.png

I don't want to display the plot on a GUI, instead, I want to save the plot to a file (say foo.png), so that, for example, it can be used in batch scripts. How do I do that?

我不想在GUI上显示这个图,而是想将这个图保存到一个文件中(比如foo.png),这样就可以在批处理脚本中使用它。我该怎么做呢?

13 个解决方案

#1


870  

While the question has been answered, I'd like to add some useful tips when using savefig. The file format can be specified by the extension:

既然问题已经得到了回答,我想在使用savefig时添加一些有用的技巧。文件格式可由扩展名指定:

savefig('foo.png')
savefig('foo.pdf')

Will give a rasterized or vectorized output respectively, both which could be useful. In addition, you'll find that pylab leaves a generous, often undesirable, whitespace around the image. Remove it with:

将分别给出一个栅格化或矢量化的输出,两者都可能有用。此外,您将发现pylab在图像周围留下了一个慷慨的、通常不受欢迎的空白。删除:

savefig('foo.png', bbox_inches='tight')

#2


124  

The solution is:

解决方案是:

pylab.savefig('foo.png')

#3


104  

As others have said, plt.savefig() or fig1.savefig() is indeed the way to save an image.

正如其他人所说,savefig()或fig1.savefig()实际上是保存图像的方法。

However I've found that in certain cases (eg. with Spyder having plt.ion(): interactive mode = On) the figure is always shown. I work around this by forcing the closing of the figure window in my giant loop, so I don't have a million open figures during the loop:

然而,我发现在某些情况下。使用Spyder的pl .ion():交互模式= On),图形总是显示。我通过在我的大循环中强制关闭图形窗口来解决这个问题,所以在循环期间我没有一百万张打开的数字:

import matplotlib.pyplot as plt
fig, ax = plt.subplots( nrows=1, ncols=1 )  # create figure & 1 axis
ax.plot([0,1,2], [10,20,3])
fig.savefig('path/to/save/image/to.png')   # save the figure to file
plt.close(fig)    # close the figure

#4


56  

Just found this link on the MatPlotLib documentation addressing exactly this issue: http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

刚刚在MatPlotLib文档中找到了这个链接,它正好解决了这个问题:http://matplotlib.org/faq/howto_faq.html#generate- images-withouthaving-window- appear

They say that the easiest way to prevent the figure from popping up is to use a non-interactive backend (eg. Agg), via matplotib.use(<backend>), eg:

他们说,防止图形弹出的最简单的方法是使用非交互式后端(例如。gg),通过matplotib.use( <端> ),例如:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('myfig')

I still personally prefer using plt.close( fig ), since then you have the option to hide certain figures (during a loop), but still display figures for post-loop data processing. It is probably slower than choosing a non-interactive backend though - would be interesting if someone tested that.

我个人还是喜欢使用plt。close(图),从那时起,您可以选择隐藏某些图形(在循环期间),但仍然显示用于后循环数据处理的图形。它可能比选择非交互式后端要慢——如果有人测试的话会很有趣。

#5


31  

If you don't like the concept of the "current" figure, do:

如果你不喜欢“当前”数字的概念,可以这样做:

import matplotlib.image as mpimg

img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)

#6


21  

The other answers are correct. However, I sometimes find that I want to open the figure object later. For example, I might want to change the label sizes, add a grid, or do other processing. In a perfect world, I would simply rerun the code generating the plot, and adapt the settings. Alas, the world is not perfect. Therefore, in addition to saving to PDF or PNG, I add:

其他的答案是正确的。但是,有时我发现我想要稍后打开这个图形对象。例如,我可能想更改标签大小、添加网格或进行其他处理。在一个完美的世界里,我只需重新运行生成情节的代码,并调整设置。唉,这个世界并不完美。因此,除了保存到PDF或PNG之外,我补充:

with open('some_file.pkl', "wb") as fp:
    pickle.dump(fig, fp, protocol=4)

Like this, I can later load the figure object and manipulate the settings as I please.

像这样,我以后可以加载figure对象并按我的意愿操作设置。

I also write out the stack with the source-code and locals() dictionary for each function/method in the stack, so that I can later tell exactly what generated the figure.

我还用源代码和local()字典把堆栈中的每个函数/方法都写出来,这样我以后就可以确切地知道是什么生成了这个图形。

NB: Be careful, as sometimes this method generates huge files.

注意,因为这个方法有时会生成大量的文件。

#7


19  

import datetime
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

# Create the PdfPages object to which we will save the pages:
# The with statement makes sure that the PdfPages object is closed properly at
# the end of the block, even if an Exception occurs.
with PdfPages('multipage_pdf.pdf') as pdf:
    plt.figure(figsize=(3, 3))
    plt.plot(range(7), [3, 1, 4, 1, 5, 9, 2], 'r-o')
    plt.title('Page One')
    pdf.savefig()  # saves the current figure into a pdf page
    plt.close()

    plt.rc('text', usetex=True)
    plt.figure(figsize=(8, 6))
    x = np.arange(0, 5, 0.1)
    plt.plot(x, np.sin(x), 'b-')
    plt.title('Page Two')
    pdf.savefig()
    plt.close()

    plt.rc('text', usetex=False)
    fig = plt.figure(figsize=(4, 5))
    plt.plot(x, x*x, 'ko')
    plt.title('Page Three')
    pdf.savefig(fig)  # or you can pass a Figure object to pdf.savefig
    plt.close()

    # We can also set the file's metadata via the PdfPages object:
    d = pdf.infodict()
    d['Title'] = 'Multipage PDF Example'
    d['Author'] = u'Jouni K. Sepp\xe4nen'
    d['Subject'] = 'How to create a multipage pdf file and set its metadata'
    d['Keywords'] = 'PdfPages multipage keywords author title subject'
    d['CreationDate'] = datetime.datetime(2009, 11, 13)
    d['ModDate'] = datetime.datetime.today()

#8


17  

After using the plot() and other functions to create the content you want, you could use a clause like this to select between plotting to the screen or to file:

在使用plot()和其他函数创建您想要的内容之后,您可以使用这样的子句在屏幕上的绘图和文件之间进行选择:

import matplotlib.pyplot as plt

fig = plt.figure(figuresize=4, 5)
# use plot(), etc. to create your plot.

# Pick one of the following lines to uncomment
# save_file = None
# save_file = os.path.join(your_directory, your_file_name)  

if save_file:
    plt.savefig(save_file)
    plt.close(fig)
else:
    plt.show()

#9


15  

I used the following:

我用以下:

import matplotlib.pyplot as plt

p1 = plt.plot(dates, temp, 'r-', label="Temperature (celsius)")  
p2 = plt.plot(dates, psal, 'b-', label="Salinity (psu)")  
plt.legend(loc='upper center', numpoints=1, bbox_to_anchor=(0.5, -0.05),        ncol=2, fancybox=True, shadow=True)

plt.savefig('data.png')  
plt.show()  
f.close()
plt.close()

I found very important to use plt.show after saving the figure, otherwise it won't work.figure exported in png

我发现使用plt很重要。保存图形后显示,否则无法工作。图导出png

#10


10  

If, like me, you use Spyder IDE, you have to disable the interactive mode with :

如果你像我一样使用Spyder IDE,你必须禁用交互模式:

plt.ioff()

plt.ioff()

(this command is automatically launched with the scientific startup)

(此命令在科学启动时自动启动)

If you want to enable it again, use :

如果你想再次启用它,请使用:

plt.ion()

plt.ion()

#11


9  

The Solution :

解决方案:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use('ggplot')
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
plt.figure()
ts.plot()
plt.savefig("foo.png", bbox_inches='tight')

If you do want to display the image as well as saving the image use:

如果你想要显示图像和保存图像使用:

%matplotlib inline

after import matplotlib

导入后matplotlib

#12


7  

You can either do:

你可以做的:

plt.show(hold=False)
plt.savefig('name.pdf')

and remember to let savefig finish before closing the GUI plot. This way you can see the image beforehand.

记得在结束GUI绘图之前让savefig完成。这样你可以提前看到图像。

Alternatively, you can look at it with plt.show() Then close the GUI and run the script again, but this time replace plt.show() with plt.savefig().

或者,您可以使用pl .show()查看它,然后关闭GUI并再次运行脚本,但这一次将pl .show()替换为pl .savefig()。

Alternatively, you can use

或者,您可以使用

fig, ax = plt.figure(nrows=1, ncols=1)
plt.plot(...)
plt.show()
fig.savefig('out.pdf')

#13


2  

#write the code for the plot     
plt.savefig("filename.png")

The file will be saved in the same directory as the python/Jupyter file running

该文件将保存在与正在运行的python/Jupyter文件相同的目录中

#1


870  

While the question has been answered, I'd like to add some useful tips when using savefig. The file format can be specified by the extension:

既然问题已经得到了回答,我想在使用savefig时添加一些有用的技巧。文件格式可由扩展名指定:

savefig('foo.png')
savefig('foo.pdf')

Will give a rasterized or vectorized output respectively, both which could be useful. In addition, you'll find that pylab leaves a generous, often undesirable, whitespace around the image. Remove it with:

将分别给出一个栅格化或矢量化的输出,两者都可能有用。此外,您将发现pylab在图像周围留下了一个慷慨的、通常不受欢迎的空白。删除:

savefig('foo.png', bbox_inches='tight')

#2


124  

The solution is:

解决方案是:

pylab.savefig('foo.png')

#3


104  

As others have said, plt.savefig() or fig1.savefig() is indeed the way to save an image.

正如其他人所说,savefig()或fig1.savefig()实际上是保存图像的方法。

However I've found that in certain cases (eg. with Spyder having plt.ion(): interactive mode = On) the figure is always shown. I work around this by forcing the closing of the figure window in my giant loop, so I don't have a million open figures during the loop:

然而,我发现在某些情况下。使用Spyder的pl .ion():交互模式= On),图形总是显示。我通过在我的大循环中强制关闭图形窗口来解决这个问题,所以在循环期间我没有一百万张打开的数字:

import matplotlib.pyplot as plt
fig, ax = plt.subplots( nrows=1, ncols=1 )  # create figure & 1 axis
ax.plot([0,1,2], [10,20,3])
fig.savefig('path/to/save/image/to.png')   # save the figure to file
plt.close(fig)    # close the figure

#4


56  

Just found this link on the MatPlotLib documentation addressing exactly this issue: http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

刚刚在MatPlotLib文档中找到了这个链接,它正好解决了这个问题:http://matplotlib.org/faq/howto_faq.html#generate- images-withouthaving-window- appear

They say that the easiest way to prevent the figure from popping up is to use a non-interactive backend (eg. Agg), via matplotib.use(<backend>), eg:

他们说,防止图形弹出的最简单的方法是使用非交互式后端(例如。gg),通过matplotib.use( <端> ),例如:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('myfig')

I still personally prefer using plt.close( fig ), since then you have the option to hide certain figures (during a loop), but still display figures for post-loop data processing. It is probably slower than choosing a non-interactive backend though - would be interesting if someone tested that.

我个人还是喜欢使用plt。close(图),从那时起,您可以选择隐藏某些图形(在循环期间),但仍然显示用于后循环数据处理的图形。它可能比选择非交互式后端要慢——如果有人测试的话会很有趣。

#5


31  

If you don't like the concept of the "current" figure, do:

如果你不喜欢“当前”数字的概念,可以这样做:

import matplotlib.image as mpimg

img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)

#6


21  

The other answers are correct. However, I sometimes find that I want to open the figure object later. For example, I might want to change the label sizes, add a grid, or do other processing. In a perfect world, I would simply rerun the code generating the plot, and adapt the settings. Alas, the world is not perfect. Therefore, in addition to saving to PDF or PNG, I add:

其他的答案是正确的。但是,有时我发现我想要稍后打开这个图形对象。例如,我可能想更改标签大小、添加网格或进行其他处理。在一个完美的世界里,我只需重新运行生成情节的代码,并调整设置。唉,这个世界并不完美。因此,除了保存到PDF或PNG之外,我补充:

with open('some_file.pkl', "wb") as fp:
    pickle.dump(fig, fp, protocol=4)

Like this, I can later load the figure object and manipulate the settings as I please.

像这样,我以后可以加载figure对象并按我的意愿操作设置。

I also write out the stack with the source-code and locals() dictionary for each function/method in the stack, so that I can later tell exactly what generated the figure.

我还用源代码和local()字典把堆栈中的每个函数/方法都写出来,这样我以后就可以确切地知道是什么生成了这个图形。

NB: Be careful, as sometimes this method generates huge files.

注意,因为这个方法有时会生成大量的文件。

#7


19  

import datetime
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

# Create the PdfPages object to which we will save the pages:
# The with statement makes sure that the PdfPages object is closed properly at
# the end of the block, even if an Exception occurs.
with PdfPages('multipage_pdf.pdf') as pdf:
    plt.figure(figsize=(3, 3))
    plt.plot(range(7), [3, 1, 4, 1, 5, 9, 2], 'r-o')
    plt.title('Page One')
    pdf.savefig()  # saves the current figure into a pdf page
    plt.close()

    plt.rc('text', usetex=True)
    plt.figure(figsize=(8, 6))
    x = np.arange(0, 5, 0.1)
    plt.plot(x, np.sin(x), 'b-')
    plt.title('Page Two')
    pdf.savefig()
    plt.close()

    plt.rc('text', usetex=False)
    fig = plt.figure(figsize=(4, 5))
    plt.plot(x, x*x, 'ko')
    plt.title('Page Three')
    pdf.savefig(fig)  # or you can pass a Figure object to pdf.savefig
    plt.close()

    # We can also set the file's metadata via the PdfPages object:
    d = pdf.infodict()
    d['Title'] = 'Multipage PDF Example'
    d['Author'] = u'Jouni K. Sepp\xe4nen'
    d['Subject'] = 'How to create a multipage pdf file and set its metadata'
    d['Keywords'] = 'PdfPages multipage keywords author title subject'
    d['CreationDate'] = datetime.datetime(2009, 11, 13)
    d['ModDate'] = datetime.datetime.today()

#8


17  

After using the plot() and other functions to create the content you want, you could use a clause like this to select between plotting to the screen or to file:

在使用plot()和其他函数创建您想要的内容之后,您可以使用这样的子句在屏幕上的绘图和文件之间进行选择:

import matplotlib.pyplot as plt

fig = plt.figure(figuresize=4, 5)
# use plot(), etc. to create your plot.

# Pick one of the following lines to uncomment
# save_file = None
# save_file = os.path.join(your_directory, your_file_name)  

if save_file:
    plt.savefig(save_file)
    plt.close(fig)
else:
    plt.show()

#9


15  

I used the following:

我用以下:

import matplotlib.pyplot as plt

p1 = plt.plot(dates, temp, 'r-', label="Temperature (celsius)")  
p2 = plt.plot(dates, psal, 'b-', label="Salinity (psu)")  
plt.legend(loc='upper center', numpoints=1, bbox_to_anchor=(0.5, -0.05),        ncol=2, fancybox=True, shadow=True)

plt.savefig('data.png')  
plt.show()  
f.close()
plt.close()

I found very important to use plt.show after saving the figure, otherwise it won't work.figure exported in png

我发现使用plt很重要。保存图形后显示,否则无法工作。图导出png

#10


10  

If, like me, you use Spyder IDE, you have to disable the interactive mode with :

如果你像我一样使用Spyder IDE,你必须禁用交互模式:

plt.ioff()

plt.ioff()

(this command is automatically launched with the scientific startup)

(此命令在科学启动时自动启动)

If you want to enable it again, use :

如果你想再次启用它,请使用:

plt.ion()

plt.ion()

#11


9  

The Solution :

解决方案:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use('ggplot')
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
plt.figure()
ts.plot()
plt.savefig("foo.png", bbox_inches='tight')

If you do want to display the image as well as saving the image use:

如果你想要显示图像和保存图像使用:

%matplotlib inline

after import matplotlib

导入后matplotlib

#12


7  

You can either do:

你可以做的:

plt.show(hold=False)
plt.savefig('name.pdf')

and remember to let savefig finish before closing the GUI plot. This way you can see the image beforehand.

记得在结束GUI绘图之前让savefig完成。这样你可以提前看到图像。

Alternatively, you can look at it with plt.show() Then close the GUI and run the script again, but this time replace plt.show() with plt.savefig().

或者,您可以使用pl .show()查看它,然后关闭GUI并再次运行脚本,但这一次将pl .show()替换为pl .savefig()。

Alternatively, you can use

或者,您可以使用

fig, ax = plt.figure(nrows=1, ncols=1)
plt.plot(...)
plt.show()
fig.savefig('out.pdf')

#13


2  

#write the code for the plot     
plt.savefig("filename.png")

The file will be saved in the same directory as the python/Jupyter file running

该文件将保存在与正在运行的python/Jupyter文件相同的目录中