Some of the astronomical research journals (ApJ, ApJL, others?) still require that figures be submitted in (encapsulated) postscript format. Since we’re otherwise living in the second decade of the 21st century, our figures frequently contain elements supported by the PDF format but not by PS, most notable among them variable element transparencies. This is the “alpha” parameter in Matplotlib, and I suppose “transparency” in more recent versions of IDL (IDL<=7 didn't support transparencies and was one of the main reasons I switched 4 years ago and for many other reasons happily never looked back).
Once I had carefully constructed PDF figures that I then needed to port to PS for submission to the journal I tried various image conversion options with ImageMagick/convert, always without much success. I learned recently that (of course) Matplotlib will easily allow you to do this at the plot generation stage with a trivial change to the plotting code. Example code is provided below with the key line obtained from pstjon@StackOverflow:
import numpy as np import matplotlib.pyplot as plt x = np.random.normal(size=5000) y = np.random.normal(size=5000) #### Normal plot plt.scatter(x, y, alpha=0.05, s=40, color='black') plt.plot([-10,10],[-10,10], color='red', linewidth=10, alpha=0.5) plt.plot([-10,10],[10,-10], color='blue', linewidth=10, alpha=0.5) plt.xlim(-10,10); plt.ylim(-10,10) plt.savefig('default.pdf') ### alphas preserved plt.savefig('default.eps') ### alphas lost #### For rasterized EPS (e.g., preserve opacity) fig = plt.figure() ax = fig.add_subplot(111) ## This is the key. elements with zorder < 1 will be rasterized ax.set_rasterization_zorder(1) ax.text(0, 5, 'This will be rasterized', size=12, zorder=0) ax.text(0, 3, 'This won\'t', size=12, zorder=1) ax.scatter(x, y, alpha=0.05, s=40, color='black', zorder=0) ax.plot([-10,10],[-10,10], color='red', linewidth=10, alpha=0.5, zorder=0) ax.plot([-10,10],[10,-10], color='blue', linewidth=10, alpha=0.5, zorder=0) ax.set_xlim(-10,10); ax.set_ylim(-10,10) plt.xlim(-10,10); plt.ylim(-10,10) fig.savefig('raster.eps', rasterized=True) fig.savefig('raster300.eps', rasterized=True, dpi=300) ### for publication
The results are compared in the image below.
This was partially inspired by a recent post at Astrobetter showing how to use rasterization to reduce figure file sizes when plotting many thousands of points. In the example shown there, I think the plot is still useless as the large majority of points are in the saturated blob in the middle of the image. The Astrobetter example (along with mine above) is just a toy demonstration, but this problem does appear up frequently in the published literature. This can be cured either by pushing alpha down further or, better yet, by showing contours rather than points where the point density is high.