42

I am using matplotlib (within pylab) to display figures. And I want to save them in .jpg format. When I simply use the savefig command with jpg extension this returns :

ValueError: Format "jpg" is not supported.

Supported formats: emf, eps, pdf, png, ps, raw, rgba, svg, svgz.

Is there a way to perform this ?

cedm34
  • 493
  • 1
  • 5
  • 5
  • Can you export to png, and convert using imagemagick? – Yann Jan 11 '12 at 21:56
  • 2
    Not directly related to your problem, but the line art typically produced by matplotlib doesn't work well with the compression algorithm used by the JPEG format which was designed for blurry photographs. Compare e.g. the sharpness of the lines in Yann's answer or http://img.labnol.org/di/jpg_vs_png.png – Benjamin Bannier Jan 12 '12 at 15:41
  • For figures showing points, lines, and/or curves, I always use a vector graphics format like eps, ps, pdf, and I think emf rather than a raster graphics format like png or jpg. This produces figures that are scaleable without resolution loss and much smaller file sizes. Going from png to pdf, you might shrink your image size from 400 kB to 40 kB. You'll get similar results with emf, and MS Office (if you aren't lucky enough to be using LaTeX) handles emf well. – Chad Feb 14 '14 at 13:55

7 Answers7

50

You can save an image as 'png' and use the python imaging library (PIL) to convert this file to 'jpg':

import Image
import matplotlib.pyplot as plt

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

The original:

enter image description here

The JPEG image:

enter image description here

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Yann
  • 33,811
  • 9
  • 79
  • 70
  • python imaging library (PIL) is not so easy to be installed on Mac OS with python 2.7.2... It's talking about "error gcc-4.0..." :-( – cedm34 Jan 12 '12 at 16:23
43

To clarify and update @neo useful answer and the original question. A clean solution consists of installing Pillow, which is an updated version of the Python Imaging Library (PIL). This is done using

pip install pillow

Once Pillow is installed, the standard Matplotlib commands

import matplotlib.pyplot as plt

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

will save the figure into a JPEG file and will not generate a ValueError any more.

Contrary to @amillerrhodes answer, as of Matplotlib 3.1, JPEG files are still not supported. If I remove the Pillow package I still receive a ValueError about an unsupported file type.

divenex
  • 15,176
  • 9
  • 55
  • 55
  • I have pillow and png works fine. I get the error "IOError: encoder error -2 when writing image file" when running exactly your code in Enthought Canopy. – Keith Jun 12 '15 at 18:21
  • @Keith the PNG format is supported out of the box by matplotlib, without the need for Pillow. This suggests that your error message is due to an issue with the Pillow installation. – divenex Jul 16 '15 at 08:39
  • For completeness: I tested the above commands to work under both Ubuntu Linux and Windows, with the [Anaconda](https://store.continuum.io/cshop/anaconda/) distribution – divenex Jul 16 '15 at 09:36
10

Just install pillow with pip install pillow and it will work.

letmaik
  • 3,348
  • 1
  • 36
  • 43
4

I just updated matplotlib to 1.1.0 on my system and it now allows me to save to jpg with savefig.

To upgrade to matplotlib 1.1.0 with pip, use this command:

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

EDIT (to respond to comment):

pylab is simply an aggregation of the matplotlib.pyplot and numpy namespaces (as well as a few others) jinto a single namespace.

On my system, pylab is just this:

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

You can see that pylab is just another namespace in your matplotlib installation. Therefore, it doesn't matter whether or not you import it with pylab or with matplotlib.pyplot.

If you are still running into problem, then I'm guessing the macosx backend doesn't support saving plots to jpg. You could try using a different backend. See here for more information.

amillerrhodes
  • 2,662
  • 1
  • 17
  • 19
  • I have matplotlib 1.1.0. But I am importing pylab on Mac therefore maybe the version of matplotlib included is not 1.1.0 but I don't konw how to be sure of that. – cedm34 Jan 12 '12 at 08:51
2

Matplotlib can handle directly and transparently jpg if you have installed PIL. You don't need to call it, it will do it by itself. If Python cannot find PIL, it will raise an error.

Davidm
  • 29
  • 1
1

I'm not sure about all versions of Matplotlib, but in the official documentation for v3.5.0 savfig allows you to pass settings through to the underlying Pillow library which anyway does the image saving. So if you want a jpg with specific compression settings for example:

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

This should give you a highly compressed jpg as the output.

Dre
  • 1,985
  • 16
  • 13
0

Just for completeness, if you also want to control the quality (i.e. compression level) of the saved result, it seems to get a bit more complicated, as directly passing plt.savefig(..., quality=5) does not seem to have an effect on the output size and quality. So, on the one hand, one could either go the way of saving the result as a png first, then reloading it with PIL, then saving it again as a jpeg, using PIL's quality parameter – similar to what is suggested in Yann's answer.

On the other hand, one can avoid this deviation of loading and saving, by using BytesIO (following the answer to 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)
simon
  • 1,503
  • 8
  • 16