geoviews icon indicating copy to clipboard operation
geoviews copied to clipboard

Specifying EPSG Projection results in ValueError or empty plot

Open scottyhq opened this issue 5 years ago • 1 comments

ALL software version info

(this library, plus any other relevant software, e.g. bokeh, python, notebook, OS, browser, etc) geoviews 1.8.2 py_0 conda-forge
bokeh 2.2.1 py37hc8dfbb8_0 conda-forge hvplot 0.6.0 pyh9f0ad1d_0 conda-forge cartopy 0.18.0 py37h891f161_2 conda-forge

Description of expected behavior and the observed behavior

Specifying projection with cartopy.crs.epsg() raises ValueError: cannot convert float NaN to integer

Complete, minimal, self-contained example code that reproduces the issue

import geoviews as gv
import geopandas as gpd
from shapely import geometry
import cartopy.crs as ccrs
import hvplot.pandas

S,N,W,E = [74.5, 80, -102, -98]
bbox = geometry.box(W,S,E,N)
gf = gpd.GeoDataFrame(geometry=[bbox], crs=4326)


crs = ccrs.epsg(3413)
print(crs.proj4_init)
print(gf.crs)

box = gf.hvplot.polygons(line_color='m', fill_color='m', fill_alpha=0.1,
                         coastline=True, projection=crs,
                         #frame_height=400, frame_width=400,
                        )
box

Stack traceback and/or browser JavaScript console output

Full traceback:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~/miniconda3/envs/intake-stac-gui/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/intake-stac-gui/lib/python3.7/site-packages/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
   1310         combined and returned.
   1311         """
-> 1312         return Store.render(self)
   1313 
   1314 

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/holoviews/core/options.py in render(cls, obj)
   1392         data, metadata = {}, {}
   1393         for hook in hooks:
-> 1394             ret = hook(obj)
   1395             if ret is None:
   1396                 continue

~/miniconda3/envs/intake-stac-gui/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/intake-stac-gui/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/intake-stac-gui/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/intake-stac-gui/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/intake-stac-gui/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/intake-stac-gui/lib/python3.7/site-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
    393                 doc = Document()
    394                 with config.set(embed=embed):
--> 395                     model = plot.layout._render_model(doc, comm)
    396                 if embed:
    397                     return render_model(model, comm)

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/panel/viewable.py in _render_model(self, doc, comm)
    416         if comm is None:
    417             comm = state._comm_manager.get_server_comm()
--> 418         model = self.get_root(doc, comm)
    419 
    420         if config.embed:

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/panel/viewable.py in get_root(self, doc, comm)
    645         """
    646         doc = doc or _curdoc()
--> 647         root = self._get_model(doc, comm=comm)
    648         self._preprocess(root)
    649         ref = root.ref['id']

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/panel/layout.py in _get_model(self, doc, root, parent, comm)
    118         if root is None:
    119             root = model
--> 120         objects = self._get_objects(model, [], doc, root, comm)
    121         props = dict(self._init_properties(), objects=objects)
    122         model.update(**self._process_param_change(props))

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/panel/layout.py in _get_objects(self, model, old_objects, doc, root, comm)
    108             else:
    109                 try:
--> 110                     child = pane._get_model(doc, root, model, comm)
    111                 except RerenderError:
    112                     return self._get_objects(model, current_objects[:i], doc, root, comm)

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/panel/pane/holoviews.py in _get_model(self, doc, root, parent, comm)
    225             plot = self.object
    226         else:
--> 227             plot = self._render(doc, comm, root)
    228 
    229         plot.pane = self

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/panel/pane/holoviews.py in _render(self, doc, comm, root)
    284             kwargs = {}
    285 
--> 286         return renderer.get_plot(self.object, **kwargs)
    287 
    288     def _cleanup(self, root):

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/holoviews/plotting/bokeh/renderer.py in get_plot(self_or_cls, obj, doc, renderer, **kwargs)
     71         combining the bokeh model with another plot.
     72         """
---> 73         plot = super(BokehRenderer, self_or_cls).get_plot(obj, doc, renderer, **kwargs)
     74         if plot.document is None:
     75             plot.document = Document() if self_or_cls.notebook_context else curdoc()

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
    238             init_key = tuple(v if d is None else d for v, d in
    239                              zip(plot.keys[0], defaults))
--> 240             plot.update(init_key)
    241         else:
    242             plot = obj

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/holoviews/plotting/plot.py in update(self, key)
    911     def update(self, key):
    912         if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 913             return self.initialize_plot()
    914         item = self.__getitem__(key)
    915         self.traverse(lambda x: setattr(x, '_updated', True))

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/geoviews/plotting/bokeh/plot.py in initialize_plot(self, ranges, plot, plots, source)
    111     def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
    112         opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
--> 113         fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
    114         if self.geographic and self.show_bounds and not self.overlaid:
    115             from . import GeoShapePlot

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/holoviews/plotting/bokeh/element.py in initialize_plot(self, ranges, plot, plots)
   2277         if plot and not self.overlaid:
   2278             self._update_plot(key, plot, element)
-> 2279             self._update_ranges(element, ranges)
   2280 
   2281         panels = []

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/geoviews/plotting/bokeh/plot.py in _update_ranges(self, element, ranges)
     90 
     91     def _update_ranges(self, element, ranges):
---> 92         super(GeoPlot, self)._update_ranges(element, ranges)
     93         if not self.geographic:
     94             return

~/miniconda3/envs/intake-stac-gui/lib/python3.7/site-packages/holoviews/plotting/bokeh/element.py in _update_ranges(self, element, ranges)
    889                 if fixed_height:
    890                     plot.frame_height = height
--> 891                     plot.frame_width = int(height/aspect)
    892                     plot.plot_width, plot.plot_height = None, None
    893                 elif fixed_width:

ValueError: cannot convert float NaN to integer

Other notes

  1. Explicitly setting frame_width and frame_height avoids the error, but the resulting plot extents are off

  2. Using cartopy.NorthPolarStereo as crs does work crs = ccrs.NorthPolarStereo(central_longitude=-45, true_scale_latitude=70)

scottyhq avatar Oct 08 '20 22:10 scottyhq

Thanks for reporting this issue!

Looking at that traceback, it can't be correct for either height or aspect to be NaN before casting to integer. I expect we need to figure out how cartopy is resulting in a NaN value...

jlstevens avatar Dec 07 '20 16:12 jlstevens