In [1]:
import geoviews as gv
import geopandas as gpd
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.io.shapereader as shpreader
import hvplot.pandas
import matplotlib.pyplot as plt
using new URL

The shapefile is available here.

It represents Little's Atlas of Coast Redwood (Sequoia Sempervirens) distribution as collected and digitized by the Conservation Biology Institute. The original dataset is available here.

In [2]:
redwood_shapefile = '/global/cfs/cdirs/m2319/Data/Redwood_SequoiaSempervirens_extentNorthAmerica/data/commondata/data0/sequsemp.shp'

Try to plot using cartopy, geoviews

This works fine.

In [3]:
redwood_shapes_c = list(shpreader.Reader(redwood_shapefile).geometries())

proj = ccrs.Mercator.GOOGLE

fig = plt.figure(figsize=(5, 5))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines(resolution='10m')
ax.add_geometries(geoms=redwood_shapes_c,
                  crs=proj,
                  edgecolor='#d95f02', 
                  facecolor='#d95f02')
ax.set_extent((-125.5, -114, 31.5, 42.5))

Try to plot using geopandas, geoviews

Geopandas can read the shapefile successfully to a GeoDataFrame and reproject it to different coordinate systems. Working from this example ("Shape" subheading), Geoviews crashes out with an attribute error, I think while trying to reproject the data.

In [4]:
redwood_shapes_gpd = gpd.read_file(redwood_shapefile)
In [16]:
redwood_shapes_gpd.geometry[2]
Out[16]:
In [15]:
gv.Shape(redwood_shapes_gpd.geometry[2])
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~/.conda/envs/water_stress_viz/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:

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/holoviews/core/dimension.py in _repr_mimebundle_(self, include, exclude)
   1302         combined and returned.
   1303         """
-> 1304         return Store.render(self)
   1305 
   1306 

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

~/.conda/envs/water_stress_viz/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 

~/.conda/envs/water_stress_viz/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):

~/.conda/envs/water_stress_viz/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 {}, {}

~/.conda/envs/water_stress_viz/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 

~/.conda/envs/water_stress_viz/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 

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/holoviews/plotting/renderer.py in components(self, obj, fmt, comm, **kwargs)
    374             doc = Document()
    375             with config.set(embed=embed):
--> 376                 model = plot.layout._render_model(doc, comm)
    377             if embed:
    378                 return render_model(model, comm)

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

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/panel/viewable.py in get_root(self, doc, comm)
    640         """
    641         doc = doc or _curdoc()
--> 642         root = self._get_model(doc, comm=comm)
    643         self._preprocess(root)
    644         ref = root.ref['id']

~/.conda/envs/water_stress_viz/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))

~/.conda/envs/water_stress_viz/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)

~/.conda/envs/water_stress_viz/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

~/.conda/envs/water_stress_viz/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):

~/.conda/envs/water_stress_viz/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()

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/holoviews/plotting/renderer.py in get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
    230             init_key = tuple(v if d is None else d for v, d in
    231                              zip(plot.keys[0], defaults))
--> 232             plot.update(init_key)
    233         else:
    234             plot = obj

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/holoviews/plotting/plot.py in update(self, key)
    876     def update(self, key):
    877         if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 878             return self.initialize_plot()
    879         item = self.__getitem__(key)
    880         self.traverse(lambda x: setattr(x, '_updated', True))

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/geoviews/plotting/bokeh/plot.py in initialize_plot(self, ranges, plot, plots, source)
    107     def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
    108         opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
--> 109         fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
    110         if self.geographic and self.show_bounds and not self.overlaid:
    111             from . import GeoShapePlot

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/holoviews/plotting/bokeh/element.py in initialize_plot(self, ranges, plot, plots, source)
   1306         # Initialize plot, source and glyph
   1307         if plot is None:
-> 1308             plot = self._init_plot(key, style_element, ranges=ranges, plots=plots)
   1309             self._init_axes(plot)
   1310         else:

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/holoviews/plotting/bokeh/element.py in _init_plot(self, key, element, plots, ranges)
    456         subplots = list(self.subplots.values()) if self.subplots else []
    457 
--> 458         axis_types, labels, plot_ranges = self._axes_props(plots, subplots, element, ranges)
    459         xlabel, ylabel, _ = labels
    460         x_axis_type, y_axis_type = axis_types

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/holoviews/plotting/bokeh/element.py in _axes_props(self, plots, subplots, element, ranges)
    364         # Get the Element that determines the range and get_extents
    365         range_el = el if self.batched and not isinstance(self, OverlayPlot) else element
--> 366         l, b, r, t = self.get_extents(range_el, ranges)
    367         if self.invert_axes:
    368             l, b, r, t = b, l, t, r

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/geoviews/plotting/plot.py in get_extents(self, element, ranges, range_type)
     71             extents = None
     72         else:
---> 73             extents = project_extents(extents, element.crs, proj)
     74         return (np.NaN,)*4 if not extents else extents

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/geoviews/util.py in project_extents(extents, src_proj, dest_proj, tol)
     93             geom_in_src_proj = geom_clipped_to_dest_proj
     94         try:
---> 95             geom_in_crs = dest_proj.project_geometry(geom_in_src_proj, src_proj)
     96         except ValueError:
     97             src_name =type(src_proj).__name__

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/cartopy/crs.py in project_geometry(self, geometry, src_crs)
    216             raise ValueError('Unsupported geometry '
    217                              'type {!r}'.format(geom_type))
--> 218         return getattr(self, method_name)(geometry, src_crs)
    219 
    220     def _project_point(self, point, src_crs):

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/cartopy/crs.py in _project_polygon(self, polygon, src_crs)
    352             is_ccw = True
    353         else:
--> 354             is_ccw = polygon.exterior.is_ccw
    355         # Project the polygon exterior/interior rings.
    356         # Each source ring will result in either a ring, or one or more

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/shapely/geometry/polygon.py in is_ccw(self)
     83     def is_ccw(self):
     84         """True is the ring is oriented counter clock-wise"""
---> 85         return bool(self.impl['is_ccw'](self))
     86 
     87     @property

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/shapely/algorithms/cga.py in is_ccw_op(ring)
     12     """Predicate implementation"""
     13     def is_ccw_op(ring):
---> 14         return signed_area(ring) >= 0.0
     15     return is_ccw_op
     16 

~/.conda/envs/water_stress_viz/lib/python3.7/site-packages/shapely/algorithms/cga.py in signed_area(ring)
      4     algorithm at: https://web.archive.org/web/20080209143651/http://cgafaq.info:80/wiki/Polygon_Area
      5     """
----> 6     xs, ys = ring.coords.xy
      7     xs.append(xs[1])
      8     ys.append(ys[1])

AttributeError: 'list' object has no attribute 'xy'
Out[15]:
:Shape   [Longitude,Latitude]
In [7]:
redwood_shapes_gpd.geometry.to_crs("EPSG:3395").plot()
Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0x2aaadcfe3d50>
In [11]:
redwood_shapes_gpd.geometry.to_crs("EPSG:4326").plot()
Out[11]:
<matplotlib.axes._subplots.AxesSubplot at 0x2aaadd32c5d0>
In [14]:
gv.Shape(redwood_shapes_gpd.geometry.to_crs("EPSG:4326"))
WARNING:param.project_path: While projecting a Polygons element from a PlateCarree coordinate reference system (crs) to a Mercator projection none of the projected paths were contained within the bounds specified by the projection. Ensure you have specified the correct coordinate system for your data.
Out[14]: