5

I would like to include a filled contour plot to a pdf document (for example a TeX document). Currently I am using pyplots contourf, and saving to pdf with pyplots savefig. The problem with this is that the size of the plots becomes rather big as compared to a high resolution png.

One way to reduce the size is of course to reduce the number of levels in the plot, but too few levels gives a poor plot. I'm searching for a simple way to for example let the colors of the plot be saved as a png, with the axes, ticks etc. to be saved vectorized.

Løiten
  • 3,185
  • 4
  • 24
  • 36
  • Can we see a typical plot ? Did you play with the nchunk parameter ? –  May 04 '16 at 13:40
  • The example given by @tom gives a typical plot. I did not play with the nchunck parameter, but for my purposes the chosen answer was sufficient. Best – Løiten May 04 '16 at 19:34

1 Answers1

13

You can do this using the Axes option set_rasterization_zorder.

Anything with a zorder less than what you set that to be will be saved as rasterized graphics, even when saving to a vector format like pdf.

For example:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(500,500)

# fig1 will save the contourf as a vector
fig1,ax1 = plt.subplots(1)
ax1.contourf(data)
fig1.savefig('vector.pdf')

# fig2 will save the contourf as a raster
fig2,ax2 = plt.subplots(1)
ax2.contourf(data,zorder=-20)
ax2.set_rasterization_zorder(-10)
fig2.savefig('raster.pdf')

# Show the difference in file size. "os.stat().st_size" gives the file size in bytes.
print os.stat('vector.pdf').st_size
# 15998481
print os.stat('raster.pdf').st_size
# 1186334

You can see this matplotlib example for more background info.


As pointed out by @tcaswell, to rasterise just one artist without having to affect its zorder, you can use .set_rasterized. However, this doesn't appear to be an option with contourf, so you would need to loop over the PathCollections created by contourf and set_rasterized on each of them. Something like this:

contours = ax.contourf(data)
for pathcoll in contours.collections:
    pathcoll.set_rasterized(True)
tmdavison
  • 64,360
  • 12
  • 187
  • 165
  • Great answer, thanks :D. For those who wonder: Artists with a lower `zorder` is drawn first, and artists with a lower value than that given in `set_rasterization_zorder`will be rasterized. – Løiten May 04 '16 at 19:28
  • You can also use `set_rasterized` on an artist to rasterize it independent of the zorder. – tacaswell May 09 '16 at 11:31
  • 1
    @tcaswell: yes, but not all artists have that option. `contourf` returns a `matplotlib.contour.QuadContourSet` instance, which doesn't have the option `set_rasterized`. You can loop over the `PathCollections` it creates in `ax.collections` and use `set_rasterized` on each of them, but I've found using `set_rasterization_zorder` tends to be a simpler option – tmdavison May 09 '16 at 11:47
  • Ah, that is QuadContourSet being a badly behaved container. – tacaswell May 09 '16 at 11:50