I'm having a problem with plotting annotations on basemap and saving the image to a file. I have seen this problem raised several times before, but in my case following the advice didn't work and then the error persists even when reversing the code back to a previously working version without annotations.
Basically, without annotations, the figure has been plotting without problem for weeks. Now if I add around 130 annotations to the graph I get:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
C:\Users\Joshua\Canopy\scripts\Client Model\nicoleheatmap3.py in <module>()
251 '''
252 #plt.show()
--> 253 plt.savefig('Demand_map.png',bbox_inches="tight",figsize=(800/96, 800/96),dpi=1600)
254 plt.close()
255
C:\Users\Joshua\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\pyplot.pyc in savefig(*args, **kwargs)
575 def savefig(*args, **kwargs):
576 fig = gcf()
--> 577 res = fig.savefig(*args, **kwargs)
578 draw() # need this if 'transparent=True' to reset colors
579 return res
C:\Users\Joshua\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\figure.pyc in savefig(self, *args, **kwargs)
1474 self.set_frameon(frameon)
1475
-> 1476 self.canvas.print_figure(*args, **kwargs)
1477
1478 if frameon:
C:\Users\Joshua\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\backends\backend_qt5agg.pyc in print_figure(self, *args, **kwargs)
159
160 def print_figure(self, *args, **kwargs):
--> 161 FigureCanvasAgg.print_figure(self, *args, **kwargs)
162 self.draw()
163
C:\Users\Joshua\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\backend_bases.pyc in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, **kwargs)
2209 orientation=orientation,
2210 bbox_inches_restore=_bbox_inches_restore,
-> 2211 **kwargs)
2212 finally:
2213 if bbox_inches and restore_bbox:
C:\Users\Joshua\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\backends\backend_agg.pyc in print_png(self, filename_or_obj, *args, **kwargs)
519
520 def print_png(self, filename_or_obj, *args, **kwargs):
--> 521 FigureCanvasAgg.draw(self)
522 renderer = self.get_renderer()
523 original_dpi = renderer.dpi
C:\Users\Joshua\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\backends\backend_agg.pyc in draw(self)
462 if __debug__: verbose.report('FigureCanvasAgg.draw', 'debug-annoying')
463
--> 464 self.renderer = self.get_renderer(cleared=True)
465 # acquire a lock on the shared font cache
466 RendererAgg.lock.acquire()
C:\Users\Joshua\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\backends\backend_agg.pyc in get_renderer(self, cleared)
479
480 if need_new_renderer:
--> 481 self.renderer = RendererAgg(w, h, self.figure.dpi)
482 self._lastKey = key
483 elif cleared:
C:\Users\Joshua\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\backends\backend_agg.pyc in __init__(self, width, height, dpi)
92 self.height = height
93 if __debug__: verbose.report('RendererAgg.__init__ width=%s, height=%s'%(width, height), 'debug-annoying')
---> 94 self._renderer = _RendererAgg(int(width), int(height), dpi, debug=False)
95 self._filter_renderers = []
96
ValueError: width and height must each be below 32768
So my first thought was that I have a problem with the way I'm adding annotations iteratively (I had other errors earlier trying to feed it an array), so hashed that code out i.e. back to my old code base, and the problem is still there. I restart the kernel in Enthought Canopy and it's happy again, then adding annotations breaks it again until a kernel restart.
This is the code:
m = Basemap(projection='merc',llcrnrlon=53.898184,llcrnrlat=24.019957,urcrnrlon=56.721985,urcrnrlat=26.076649,lon_0=55.545,lat_0=24.735,resolution='i')
base_image = plt.imread("UAEpeninsulagrey.jpg")
implot = plt.imshow(base_image)
m.imshow(base_image,origin='upper')
a,b = m(preparePlot[1],preparePlot[0])
m.scatter(a,b,marker="o",s=preparePlot[2],color="#0000FF",alpha=0.5,)
c,d = m(preparePlot[4],preparePlot[3])
m.scatter(c,d,marker="o",s=6,color="#FF0000",alpha=0.5,)
'''
for t in range(len(annotations[0])):
x,y = m(annotations[1][t],annotations[0][t])
x2,y2 = m(annotations[4][t],annotations[3][t])
plt.annotate(annotations[2][t],xy=(x,y),xytext=(x2,y2),arrowprops=dict(facecolor='black', shrink=0.05),fontsize=2)
'''
#plt.show()
plt.savefig('Demand_map.png',bbox_inches="tight",figsize=(800/96, 800/96),dpi=1600)
plt.close()
Some other strange things. I believe I'm explicit and correct in limiting the width and height already in plt.savefig
(taken from previous SO threads e.g. this ) that this shouldn't be happening? Also, plt.show()
does not throw an error. I require the high resolution to be able to zoom in to the map at street level. I have been able to get single annotations onto the image with no problem, even annotations for locations outside of the map area, which I thought could have been causing it to try display something way outside of the image.
Setting DPI down to 200 does not remove the error. Renaming annotations
array didn't make any difference (in case it somehow caused problems for basemap internals).
Does anyone have any suggestions on how to stop this? Have I incorrectly set something up in plt.savefig
? Many thanks in advance.
P.S. The annotations array:
annotations[0][0]
Out[14]: 26.053275624999998
annotations[1][0]
Out[15]: 56.068128225
annotations[2][0]
Out[16]: 'Tot: 1, 0%'
annotations[3][0]
Out[17]: 26.043275624999996
annotations[4][0]
Out[18]: 56.058128225000004