Vector and raster in one with Matplotlib

Vector images are great, except when they shouldn’t be vector. Figures with intricate detail can actually benefit from being rasterized. This can reduce file size and help the figure load more quickly. Python’s Matplotlib has an option to rasterize certain elements, but it doesn’t always work as simply as expected.

This post describes a function that (i) lets you rasterize any chosen elements when you export the figure and (ii) overcomes problems with the current implementation of rasterizing objects with Matplotlib.

How to rasterize in Matplotlib

For most plot types, it is as simple as including

rasterized=True

in the call to, say, pcolormesh or scatter. For example,

from numpy.random import randn
N = 10000
plt.scatter(x=randn(N), y=randn(N), s=20*randn(N),
            rasterized=True)

The resolution of the rasterization is set by the dpi argument when saving:

plt.savefig('output.pdf', dpi=300)

Simplifying matters

Setting rasterized=True does not always work as easily as you might expect. For example, filled contour plots (plt.contourf) appear to ignore the setting and Basemap maps (m.fillcontinents) don’t give the option. Furthermore, it would be simpler if we could specify which objects to rasterize when we export the figure as opposed to early in the code. For these reasons, I have developed a function entitled rasterize_and_save that works much like plt.savefig, but takes as an argument a list of objects to rasterize.

Consider an example containing various plot types. We want to rasterize all but the line plot.

from numpy.random import randn
X, Y, Z = randn(9, 9), randn(9, 9), randn(9, 9)

fig, axs = plt.subplots(ncols=2, nrows=2)
(ax1, ax2), (ax3, ax4) = axs

cax1 = ax1.contourf(Z)
cax2 = ax2.scatter(X, Y, s=Z)
cax3 = ax3.pcolormesh(Z)
cax4 = ax4.plot(Z[:, 0])

rasterize_list = [cax1, cax2, cax3]
rasterize_and_save('out.svg', rasterize_list, dpi=300)

All but the last two lines will be familiar to Matplotlib users. The penultimate line specifies which objects will be rasterized. The final line exports the figure as an svg image at a resolution of 300 dpi. Here’s the (annotated) result:

rasterize_example.svg

Keeping some of the panels as vector elements is as simple as changing the objects contained in rasterize_list. Also, note how the contour plot is rasterized. This works because the rasterize_and_save function does the hard work of changing the rasterized setting on each filled contour individually.

Advertisements

Author: hugke729

PhD student in physical oceanography

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s