Error when overlaying `hv.Tiles` with a `gv.Points` element that has wrong xlim/ylim defined, with Matplotlib
This snippet sets the xlim and ylim opts of a gv.Points element to values that make no sense, and tries to overlay this element to an hv.Tiles element. Even if it's expected that there's some kind of error, the one I got with the Matplotlib backend felt way too cryptic, so I'm opening an issue to see if there would be a way to catch the error and improve the error message.
import geoviews as gv
import holoviews as hv
import cartopy
import pandas as pd
import numpy as np
gv.extension('matplotlib')
df_pts = pd.DataFrame(np.random.randn(100, 2), columns=['x', 'y'])
points = gv.Points(df_pts, crs=cartopy.crs.PlateCarree()).opts(xlim=(20000000, 40000000), ylim=(20000000, 400000000))
tiles = hv.element.tile_sources['EsriImagery']()
tiles * points
WARNING:param.GeoOverlayPlot07187: No plotting class for Tiles type and matplotlib backend found.
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/PIL/ImageFile.py in _save(im, fp, tile, bufsize)
503 try:
--> 504 fh = fp.fileno()
505 fp.flush()
AttributeError: '_idat' object has no attribute 'fileno'
During handling of the above exception, another exception occurred:
SystemError Traceback (most recent call last)
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/IPython/core/formatters.py in __call__(self, obj, include, exclude)
968
969 if method is not None:
--> 970 return method(include=include, exclude=exclude)
971 return None
972 else:
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
1314 combined and returned.
1315 """
-> 1316 return Store.render(self)
1317
1318
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/holoviews/core/options.py in render(cls, obj)
1403 data, metadata = {}, {}
1404 for hook in hooks:
-> 1405 ret = hook(obj)
1406 if ret is None:
1407 continue
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in pprint_display(obj)
280 if not ip.display_formatter.formatters['text/plain'].pprint:
281 return None
--> 282 return display(obj, raw_output=True)
283
284
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in display(obj, raw_output, **kwargs)
250 elif isinstance(obj, (CompositeOverlay, ViewableElement)):
251 with option_state(obj):
--> 252 output = element_display(obj)
253 elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
254 with option_state(obj):
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in wrapped(element)
144 try:
145 max_frames = OutputSettings.options['max_frames']
--> 146 mimebundle = fn(element, max_frames=max_frames)
147 if mimebundle is None:
148 return {}, {}
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in element_display(element, max_frames)
190 return None
191
--> 192 return render(element)
193
194
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/holoviews/ipython/display_hooks.py in render(obj, **kwargs)
66 renderer = renderer.instance(fig='png')
67
---> 68 return renderer.components(obj, **kwargs)
69
70
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
448 return data, {}
449 else:
--> 450 html = self._figure_data(plot, fmt, as_script=True, **kwargs)
451 data['text/html'] = html
452
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/holoviews/plotting/mpl/renderer.py in _figure_data(self, plot, fmt, bbox_inches, as_script, **kwargs)
173 pass
174 bytes_io = BytesIO()
--> 175 fig.canvas.print_figure(bytes_io, **kw)
176 data = bytes_io.getvalue()
177
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2259 orientation=orientation,
2260 bbox_inches_restore=_bbox_inches_restore,
-> 2261 **kwargs)
2262 finally:
2263 if bbox_inches and restore_bbox:
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/matplotlib/backend_bases.py in wrapper(*args, **kwargs)
1667 kwargs.pop(arg)
1668
-> 1669 return func(*args, **kwargs)
1670
1671 return wrapper
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/matplotlib/backends/backend_agg.py in print_png(self, filename_or_obj, metadata, pil_kwargs, *args)
509 mpl.image.imsave(
510 filename_or_obj, self.buffer_rgba(), format="png", origin="upper",
--> 511 dpi=self.figure.dpi, metadata=metadata, pil_kwargs=pil_kwargs)
512
513 def print_to_buffer(self):
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/matplotlib/image.py in imsave(fname, arr, vmin, vmax, cmap, format, origin, dpi, metadata, pil_kwargs)
1614 pil_kwargs.setdefault("format", format)
1615 pil_kwargs.setdefault("dpi", (dpi, dpi))
-> 1616 image.save(fname, **pil_kwargs)
1617
1618
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/PIL/Image.py in save(self, fp, format, **params)
2233
2234 try:
-> 2235 save_handler(self, fp, filename)
2236 finally:
2237 # do what we can to clean up
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/PIL/PngImagePlugin.py in _save(im, fp, filename, chunk, save_all)
1347 _write_multiple_frames(im, fp, chunk, rawmode)
1348 else:
-> 1349 ImageFile._save(im, _idat(fp, chunk), [("zip", (0, 0) + im.size, 0, rawmode)])
1350
1351 if info:
~/miniconda3/envs/hvplot-dev37/lib/python3.7/site-packages/PIL/ImageFile.py in _save(im, fp, tile, bufsize)
510 if o > 0:
511 fp.seek(o)
--> 512 e.setimage(im.im, b)
513 if e.pushes_fd:
514 e.setfd(fp)
SystemError: tile cannot extend outside image
Note that here tile doesn't refer to a geo-tile, it's related to PIL.
Removing .opts(xlim=(20000000, 40000000), ylim=(20000000, 400000000)) fixes the code, i.e. there's no more error (but of course the tiles are not plotted, since there's no matplotlib implementation for holoviews Tiles elements).
Is there a good reason not to have Tiles plotting for mpl in HoloViews, given that we have it for GeoViews?