holoviz / hvplot

A high-level plotting API for pandas, dask, xarray, and networkx built on HoloViews
https://hvplot.holoviz.org
BSD 3-Clause "New" or "Revised" License
1.14k stars 108 forks source link

"AttributeError: 'DataFrame' object has no attribute 'crs'" for spatialpandas polygons #1457

Closed Azaya89 closed 13 hours ago

Azaya89 commented 1 week ago

ALL software version info

Software Version Info ```plaintext hvPlot = 0.11.1 python = 3.11 dask = 2024.10 ```

Description of expected behavior and the observed behavior

hvPlot polygon plot throws an attribute error when used with a tile source

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

import dask.dataframe as dd
import spatialpandas as spd
import hvplot.dask # noqa

square = spd.geometry.Polygon([(0.0, 0), (0, 1), (1, 1), (1, 0)])
sdf = spd.dask.GeoDataFrame({'geometry': spd.GeoSeries([square, square]), 'name': ['A', 'B']})
sddf = dd.from_pandas(sdf, npartitions=2)

sddf.hvplot.polygons(tiles=True)

Stack traceback and/or browser JavaScript console output

AttributeError                            Traceback (most recent call last)
Cell In[1], line 9
      6 sdf = spd.dask.GeoDataFrame({'geometry': spd.GeoSeries([square, square]), 'name': ['A', 'B']})
      7 sddf = dd.from_pandas(sdf, npartitions=2)
----> 9 sddf.hvplot.polygons(tiles=True)

File ~/hvplot/plotting/core.py:1776, in hvPlotTabular.polygons(self, x, y, c, **kwds)
   1735 def polygons(self, x=None, y=None, c=None, **kwds):
   1736     """
   1737     Polygon plot for geopandas dataframes.
   1738 
   (...)
   1774         chicago.hvplot.polygons(geo=True, c='POP2010', hover_cols='all')
   1775     """
-> 1776     return self(x, y, c=c, kind='polygons', **kwds)

File ~/hvplot/plotting/core.py:95, in hvPlotBase.__call__(self, x, y, kind, **kwds)
     92         plot = self._get_converter(x, y, kind, **kwds)(kind, x, y)
     93         return pn.panel(plot, **panel_dict)
---> 95 return self._get_converter(x, y, kind, **kwds)(kind, x, y)

File ~/hvplot/converter.py:1724, in HoloViewsConverter.__call__(self, kind, x, y)
   1721                 dataset = Dataset(data)
   1722             dataset = redim_(dataset, **self._redim)
-> 1724         obj = method(x, y)
   1725         obj._dataset = dataset
   1727 if self.crs and self.project:
   1728     # Apply projection before rasterizing

File ~/hvplot/converter.py:2940, in HoloViewsConverter.polygons(self, x, y, data)
   2938 def polygons(self, x=None, y=None, data=None):
   2939     self._error_if_unavailable('polygons')
-> 2940     return self._geom_plot(x, y, data, kind='polygons')

File ~/hvplot/converter.py:2894, in HoloViewsConverter._geom_plot(self, x, y, data, kind)
   2893 def _geom_plot(self, x=None, y=None, data=None, kind='polygons'):
-> 2894     data, x, y, _ = self._process_gridded_args(data, x, y, z=None)
   2895     params = dict(self._relabel)
   2897     if not (x and y):

File ~/hvplot/converter.py:2726, in HoloViewsConverter._process_gridded_args(self, data, x, y, z)
   2723     post_not_found, data = process_derived_datetime_pandas(data, not_found, self.indexes)
   2724     self.variables.extend([item for item in not_found if item not in post_not_found])
-> 2726 data, x, y = self._process_tiles_without_geo(data, x, y)
   2727 return data, x, y, z

File ~/hvplot/converter.py:2174, in HoloViewsConverter._process_tiles_without_geo(self, data, x, y)
   2171     return data, x, y
   2173 if is_geodataframe(data):
-> 2174     if data.crs is not None:
   2175         data = data.to_crs(epsg=3857)
   2176     return data, x, y

File ~/dask/dataframe/core.py:5050, in DataFrame.__getattr__(self, key)
   5048     object.__getattribute__(self, key)
   5049 else:
-> 5050     raise AttributeError("'DataFrame' object has no attribute %r" % key)

AttributeError: 'DataFrame' object has no attribute 'crs'
hoxbro commented 1 week ago

Also, without dask:

import hvplot.pandas
import spatialpandas as spd

square = spd.geometry.Polygon([(0.0, 0), (0, 1), (1, 1), (1, 0)])
sdf = spd.GeoDataFrame({"geometry": spd.GeoSeries([square, square]), "name": ["A", "B"]})
sdf.hvplot.polygons(tiles=True)