Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib plots lose transparency when saving as .pdf

I'm seeing exactly the same issue as this one: Matplotlib Plots Lose Transparency When Saving as .ps/.eps except I am trying to output to PDF rather than ps/eps.

The answers to the previous question point out that eps does not support transparency and suggest either rasterising or saving as a PDF. I do get correct looking output when I save as png, so it seems as though matplotlib is dealing with the transparency correctly, but the backend is failing. Clearly PDF does support transparency, so it's not a problem with the format I'm trying to use.

I'm running in OS X (Yosemite) with the default MacOSX matplotlib backend and using matplotlib 1.4.1. Is there any reason why this setup should fail to produce transparent PDF output?

This used to work in the past (with OS X Mavericks and an earlier version of matplotlib) but I'm not sure exactly what change has caused this problem.

If the following code is run, the problem can be seen in with_hatch.pdf, but not in any of the other output files.

#! /usr/bin/env python
import matplotlib.pyplot as plt

fig = plt.figure( figsize=(6, 6), dpi=100, facecolor='white' )
ax = fig.add_axes( [0.15, 0.1, 0.8, 0.85] )

bin_edges = [0.0, 0.5, 0.5, 1.0, 1.0, 1.5, 1.5, 2.0, 2.0, 2.5, 2.5, 3.0, 3.0, 3.5, 3.5, 4.0, 4.0, 4.5, 4.5, 5.0, 5.0, 5.5, 5.5, 6.0, 6.0, 7.0, 7.0, 8.0]
y_low     = [0.9581631739289882, 0.9581631739289882, 0.8966054746563691, 0.8966054746563691, 0.8369962202270926, 0.8369962202270926, 0.7824880045351325, 0.7824880045351325, 0.7231695683685057, 0.7231695683685057, 0.6673767757896321, 0.6673767757896321, 0.6083447707111752, 0.6083447707111752, 0.5602384968623321, 0.5602384968623321, 0.5109567893600544, 0.5109567893600544, 0.4707872827805316, 0.4707872827805316, 0.4304527769718274, 0.4304527769718274, 0.39024135798617826, 0.39024135798617826, 0.3593458738615755, 0.3593458738615755, 0.3275704585658484, 0.3275704585658484]
y_high    = [0.9762065896798683, 0.9762065896798683, 0.9227253843496172, 0.9227253843496172, 0.8738222849514, 0.8738222849514, 0.8299500683866315, 0.8299500683866315, 0.7810616940586165, 0.7810616940586165, 0.7357506442258693, 0.7357506442258693, 0.6852756294051707, 0.6852756294051707, 0.6441575476130643, 0.6441575476130643, 0.5987788803224889, 0.5987788803224889, 0.5630257208701298, 0.5630257208701298, 0.5274860424153797, 0.5274860424153797, 0.4915335923551736, 0.4915335923551736, 0.46502435263727837, 0.46502435263727837, 0.43196895235913746, 0.43196895235913746]

ax.fill_between( bin_edges, y_low, y_high, facecolor='green', edgecolor='white', alpha=0.4 )

plt.savefig( 'without_hatch.pdf' )
plt.savefig( 'without_hatch.png' )

ax.fill_between( bin_edges, y_low, y_high, facecolor='green', edgecolor='white', hatch='xxxx', alpha=0.4 )

plt.savefig( 'with_hatch.pdf' )
plt.savefig( 'with_hatch.png' )

Now submitted to matplotlib bug tracker at: https://github.com/matplotlib/matplotlib/issues/3841

like image 492
JamesR Avatar asked Nov 23 '14 21:11

JamesR


People also ask

How do I save a matplotlib graph as a PDF?

To save the file in PDF format, use savefig() method where the image name is myImagePDF. pdf, format = ”pdf”. To show the image, use the plt. show() method.

How do I make matplotlib transparent?

(To make a patch completely transparent, we can either set the alpha to 0, or set the facecolor to 'none' (as a string, not the object None !))

How do I save a transparent image in Python?

Use the matplotlib savefig function with the keyword argument transparent=True to save the image as a png file. Of course, that plot doesn't demonstrate the transparency. Here's a screenshot of the PNG file displayed using the ImageMagick display command.

How do I save matplotlib without displaying?

We can simply save plots generated from Matplotlib using savefig() and imsave() methods. If we are in interactive mode, the plot might get displayed. To avoid the display of plot we use close() and ioff() methods.


2 Answers

Work around the problem?

1) You might be able to export as an alpha-supporting PNG, and then wrap that in a PDF, but you still lose all the line art in favor of a rasterized image... probably not what you want.

2) If different layers have different alpha settings, you might be able to render the individual layers to separate PDFs, and then import them and wrap'em in PDF-native alpha. That'd take some moderate PDF-fu, but should be quite doable. On the other hand, if the alpha values vary within a given area, this isn't gonna work.

like image 87
Mark Storer Avatar answered Oct 12 '22 06:10

Mark Storer


Add this line after setting up the axis you want to have transparency and before you save the figure:

ax.set_rasterized(True)
plt.savefig("fig.pdf")

This worked for my in Python 3 on MacOS Big Sur.

Documentation for this method can be found here.

like image 34
Joseph Farah Avatar answered Oct 12 '22 06:10

Joseph Farah