8

I usually use ax.set_rasterized(True) to rasterize the figure so that it could handle transparency when saved as in eps format, but the rasterization also blurs the axis labels and ticklabels, so is there a way to rasterize only patches within the axis rather than the whole figure? or is there a better around for exporting eps format with transparency? Thanks.

nye17
  • 11,197
  • 10
  • 50
  • 62
  • 1
    I just discovered the set_zorder and set_rasterization_zorder, I think they would be helpful, but still digging the documentation, still any help is appreciated. – nye17 Apr 06 '12 at 21:31
  • Can't you use `pdf`? It would preserve the transparency without rasterisation. – Avaris Apr 06 '12 at 21:49
  • @Avaris unfortunately I can not use pdf, but have to stick with eps, so rasterization seems to be the only way out. – nye17 Apr 06 '12 at 22:02
  • 2
    Ah, yes. Looks like `set_rasterization_zorder` is the way to go. Check [this](http://matplotlib.sourceforge.net/examples/misc/rasterization_demo.html). – Avaris Apr 06 '12 at 22:33
  • @Avaris still cannot make it work, the object I want to rasterize is a ax.fill_between() object and the "zorder" trick mysteriously shift the object outside of the axis, weird. – nye17 Apr 08 '12 at 04:59
  • Can you post an example? The one I tried seems to be working perfectly. – Avaris Apr 09 '12 at 16:14

2 Answers2

8

As matplotlib Artists can be rasterized, any class derived from Artist (http://matplotlib.sourceforge.net/api/artist_api.html) can be rasterized with the keyword rasterized set to True. So you can only rasterize your patches.

I just tried some combinations and it seems to work. However the quality seems to be not very good (see also http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg13276.html).

import numpy as np
import matplotlib.pyplot as plt 


def add_patch(ax, **kwargs):
    if 'rasterized' in kwargs and kwargs['rasterized']:
        ax.set_rasterization_zorder(0)
    ax.fill_between(np.arange(1, 10), 1, 2, zorder=-1, **kwargs)
    ax.set_xlim(0, 10) 
    ax.set_ylim(0, 3)
    if 'alpha' in kwargs and kwargs['alpha'] < 1:
        txt = 'This patch is transparent!'
    else:
        txt = 'This patch is not transparent!'
    ax.text(5, 1.5, txt, ha='center', va='center', fontsize=25, zorder=-2,
            rasterized=True)

fig, axes = plt.subplots(nrows=4, sharex=True)
add_patch(axes[0], alpha=0.2, rasterized=False)
add_patch(axes[1], alpha=0.2, rasterized=True)
add_patch(axes[2], rasterized=False)
add_patch(axes[3], rasterized=True)

plt.tight_layout()
plt.savefig('rasterized_transparency.eps')

I converted the eps to png to show it in the browser:

rasterized_transparency.png

See also: How to save figures to pdf as raster images in matplotlib.

Community
  • 1
  • 1
bmu
  • 30,517
  • 11
  • 84
  • 101
  • Thanks, I will try your example and have it tested on my own codes ASAP. Answer will be accepted by then ;-). – nye17 May 14 '12 at 00:30
2

The results are better if you specify dpi - which seems to default to quite a low value. For example, change the last line to

plt.savefig('rasterized_transparency.eps',dpi=200)

and the file grows to 4.5M, and looks fine in Acrobat up to 200% magnification. However I agree that there are probably more compact formats that support transparency.

bdb112
  • 21
  • 1