I'm struggling with the pdf backend of matplotlib and the contourf function. I try to plot forbidden areas on a 2D colored map. The forbidden areas are represented by hatched contourf with transparent (alpha=0.4) black color. the used code is given below, with two classes written to generate a user defined legend:
import matplotlib
print matplotlib.__version__
import matplotlib.patches as mpatches
class ConstrainedArea(object):
def __init__(self,axe,_xdata,_ydata,_zdata,boundaries,fc='none',ec='none',lw=None,alpha=None,hatch='//',ls='-',fill=False,label=None):
self.bnd = boundaries
self.fc = fc
self.ec = ec
self.lw = lw
self.ls = ls
self.al = alpha
self.hh = hatch
self.fl = fill
self.lb = label
self.ctr = axe.contour(_xdata,_ydata,_zdata,boundaries,linewidths=lw,colors=ec,linestyles=ls)
#self.ctf = axe.contourf(_xdata,_ydata,_zdata,boundaries,hatches=hatch,colors=fc,facecolors=fc,alpha=alpha)
self.ctf = axe.contourf(_xdata,_ydata,_zdata,boundaries,hatches=hatch,colors=fc,alpha=alpha,antialiased=False)
pass
class ConstrainedAreaHandler(object):
def legend_artist(self,legend,orig_handle,fontsize,handlebox):
x0,y0 = handlebox.xdescent,handlebox.ydescent
wi,he = handlebox.width,handlebox.height
patch = mpatches.Rectangle([x0,y0],wi,he,facecolor=orig_handle.fc,edgecolor=orig_handle.ec,hatch=orig_handle.hh,lw=orig_handle.lw,ls=orig_handle.ls,fill=orig_handle.fl,transform=handlebox.get_transform(),label=orig_handle.lb)
handlebox.add_artist(patch)
if __name__ == "__main__":
matplotlib.rcParams['backend'] = 'PDF'
import numpy,matplotlib.pyplot as plt
xs, ys = numpy.mgrid[0:30, 0:40]
zs = (xs - 15) ** 2 + (ys - 20) ** 2 + (numpy.sin(ys) + 10) ** 2
fig = plt.figure('test',figsize=(16.0,11.8875))
axe = fig.add_subplot(111)
pcm = axe.pcolormesh(xs,ys,zs,shading='gouraud')
cas = []
for bnd,hch,ls,lb in zip([[zs.min(),200],[400,zs.max()]],['/','\\'],['-','--'],[r'$f<200$',r'$f>400$']):
cas.append(ConstrainedArea(axe,xs,ys,zs,bnd,hatch=hch,fc='k',ec='k',lw=3,ls=ls,alpha=0.2,fill=False,label=lb))
cbr = fig.colorbar(pcm)
legframe = axe.legend(cas,[c.lb for c in cas],loc=3,handler_map={ConstrainedArea:ConstrainedAreaHandler()},ncol=3,fontsize=matplotlib.rcParams['font.size']*1.2**4,numpoints=1,framealpha=0.8)
#fig.savefig('test.pdf',bbox_inches='tight',facecolor='none',edgecolor='none',transparent=True)
fig.savefig('test.pdf',bbox_inches='tight',transparent=True)
After reading the tracks on matplotlib issues GitHub matplotlib issue 3023, and GitHub matplotlib issue 7421, I installed matplotlib 2.0.0 thinking it would solve my problem, but it didn't.
PROBLEM DEFINITION
Using the pdf backend I save the result as pdf, but reading the same file with evince, okular, or Acrobat Reader gives different screenshots, as illustrated on the figures below:
INFORMATION
The expected output is the one given by evince (visible hatches). As already mentioned in other tracks, the rasterization of the contourf object does give the expected result but I need vectorial images. Furthermore, if rasterized hatches are used with high dpi (>300), the hatch width tends to 0 yielding wrong output. Finally I found this track matplotlib generated PDF cannot be viewed with acrobat reader issue which yielded this workaround solution :
- open the matplotlib output pdf file with evince
- print it to pdf
- vizualise the evince-printed output with okular
which gives the screenshot below:
Thanks a lot in advance for any explanation or solution for this problem. Don't hesitate if orther details/information are needed,
Tariq