4

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:screenshot of picture as read with evince screenshot as read with okular

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 :

  1. open the matplotlib output pdf file with evince
  2. print it to pdf
  3. vizualise the evince-printed output with okular which gives the screenshot below: enter image description here

Thanks a lot in advance for any explanation or solution for this problem. Don't hesitate if orther details/information are needed,

Tariq

Community
  • 1
  • 1
aTben0
  • 314
  • 1
  • 6
  • 2
    I've tested with 3 other programs (Foxit reader, sumatra, win8 reader app) and they all show different results as well, [see picture here](https://i.stack.imgur.com/epOyg.png). – ImportanceOfBeingErnest Mar 05 '17 at 18:13
  • @ImportanceOfBeingErnest Thanks for this check. Do you have any idea on a reason or explanation for this problem. Actually even the workaround proposed in the question is not so efficient. Would you have another way in matplotlib to obtain the same result without creating the hatched areas directly in the contour fonction which seems to take the blame for this behaviour. Thanks in advance. – aTben0 Mar 14 '17 at 12:34

0 Answers0