Matplotlib如何以JPEG格式保存图像?

42

我正在使用matplotlib(在pylab中)显示图形。我想将它们保存为.jpg格式。当我简单地使用带有jpg扩展名的savefig命令时,会返回:

ValueError: Format "jpg" is not supported.

支持的格式:emf、eps、pdf、png、ps、raw、rgba、svg、svgz。

是否有一种方法可以执行此操作?


你能导出为png格式并使用imagemagick进行转换吗? - Yann
2
不直接与您的问题相关,但是由matplotlib生成的线条艺术通常与JPEG格式使用的压缩算法不兼容,该算法设计用于模糊的照片。例如,比较Yann的答案或http://img.labnol.org/di/jpg_vs_png.png中线条的清晰度。 - Benjamin Bannier
对于显示点、线和/或曲线的图形,我总是使用矢量图格式,如eps、ps、pdf,而不是像png或jpg这样的栅格图形格式。这会产生可无损缩放且文件大小更小的图片。从png转换为pdf,您可能会将图像大小从400 kB 缩小到40 kB。使用emf也会得到类似的结果,并且MS Office(如果您没有足够幸运地使用LaTeX)可以很好地处理emf。 - Chad
7个回答

50
你可以将图像保存为“png”格式,并使用Python Imaging Library(PIL)将该文件转换为“jpg”格式。
import Image
import matplotlib.pyplot as plt

plt.plot(range(10))
plt.savefig('testplot.png')
Image.open('testplot.png').save('testplot.jpg','JPEG')

原始图像:

在此输入图片描述

JPEG图像:

在此输入图片描述


Python Imaging Library(PIL)在Mac OS上安装起来并不容易,特别是在Python 2.7.2版本上... 它会出现“错误gcc-4.0”的提示 :-( - cedm34

43

为了澄清并更新@neo的有用答案和原始问题。一种简洁的解决方案是安装Pillow,它是Python Imaging Library(PIL)的更新版本。这可以通过以下方式实现

pip install pillow

一旦安装了Pillow,标准的Matplotlib命令

import matplotlib.pyplot as plt

plt.plot([1, 2])
plt.savefig('image.jpg')

将图形保存为JPEG文件,将不再产生ValueError错误。

与@amillerrhodes的回答相反,在Matplotlib 3.1版本中,仍不支持JPEG文件。如果我删除Pillow包,仍会收到有关不支持文件类型的ValueError错误。


我已经安装了Pillow和png,这些工具都很好用。但是,当我在Enthought Canopy中运行你的代码时,出现了"IOError: encoder error -2 when writing image file"的错误提示。 - Keith
@Keith,PNG格式在matplotlib中可以直接支持,无需使用Pillow。这表明您的错误信息可能是由于Pillow安装问题引起的。 - divenex
为了完整性:我测试了上述命令在Ubuntu Linux和Windows下均可工作,使用Anaconda发行版。 - divenex

10

只需使用 pip install pillow 安装pillow即可正常工作。


4

我刚刚在我的系统上将matplotlib更新到了1.1.0版本,现在它允许我使用savefig保存为jpg格式。

要使用pip升级到matplotlib 1.1.0,请使用以下命令:

pip install -U 'http://sourceforge.net/projects/matplotlib/files/matplotlib/matplotlib-1.1.0/matplotlib-1.1.0.tar.gz/download'

编辑(回复评论):

pylab仅仅是matplotlib.pyplot和numpy命名空间(以及其他一些命名空间)的聚合,形成一个单独的命名空间。

在我的系统上,pylab只是这样的:

from matplotlib.pylab import *
import matplotlib.pylab
__doc__ = matplotlib.pylab.__doc__

你可以看到,pylab仅是你matplotlib安装中的另一个命名空间。因此,无论你使用pylab还是matplotlib.pyplot导入它都没有关系。
如果你仍然遇到问题,那么我猜测macosx后端不支持将图形保存为jpg格式。你可以尝试使用其他后端。有关更多信息,请参见这里

我有matplotlib 1.1.0版本。但是在Mac上导入pylab时,可能包含的matplotlib版本不是1.1.0,但我不知道如何确定。 - cedm34

2

如果您已经安装了PIL,Matplotlib可以直接透明地处理jpg格式的图片。您不需要调用它,它会自动完成。如果Python找不到PIL,则会引发错误。


1

我不确定所有Matplotlib版本,但在官方文档中,例如v3.5.0的savfig函数可以允许你传递设置到底层的Pillow库,该库实际上负责图像保存。因此,如果你需要一个具有特定压缩设置的jpg格式的图像:

import matplotlib.pyplot as plt
plt.plot(...)  # Plot stuff
plt.savefig('filename.jpg', pil_kwargs={
    'quality': 20,
    'subsampling': 10
})

这应该可以让您得到高度压缩的 jpg 作为输出。

0

为了完整起见,如果您还想控制保存结果的质量(即压缩级别),似乎会变得更加复杂,因为直接传递plt.savefig(..., quality=5)似乎对输出大小和质量没有影响。因此,一方面,可以先将结果保存为png,然后使用PIL重新加载它,然后再次保存为jpeg,使用PILquality参数-类似于Yann答案中建议的内容。

另一方面,可以通过使用BytesIO来避免这种加载和保存的偏差(按照this question的答案):

from io import BytesIO
import matplotlib.pyplot as plt
from PIL import Image

buf = BytesIO()

plt.plot(...)  # Plot something here
plt.savefig(buf)
Image.open(buf).convert("RGB").save("testplot.jpg", quality=5)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接