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.12k stars 108 forks source link

hvplot fails for DataFrame with index name of 0 #1020

Open dwr-psandhu opened 1 year ago

dwr-psandhu commented 1 year ago

ALL software version info

hvplot 0.8.1

Description of expected behavior and the observed behavior

a DataFrame has a index named 0 ( the int type). This is allowed i guess

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

df2 = pd.DataFrame([1,2,3],pd.date_range(start='2000-01-01',periods=3, freq='6T'))
df2.index.name = 0
df2.hvplot() # fails

Stack traceback and/or browser JavaScript console output

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[49], line 7
      3 df2.index.name = 0
      5 df2
----> 7 df2.hvplot()

File ~/miniforge3/envs/schism_viz/lib/python3.8/site-packages/hvplot/plotting/core.py:92, in hvPlotBase.__call__(self, x, y, kind, **kwds)
     89         plot = self._get_converter(x, y, kind, **kwds)(kind, x, y)
     90         return pn.panel(plot, **panel_dict)
---> 92 return self._get_converter(x, y, kind, **kwds)(kind, x, y)

File ~/miniforge3/envs/schism_viz/lib/python3.8/site-packages/hvplot/converter.py:1240, in HoloViewsConverter.__call__(self, kind, x, y)
   1238                 dataset = Dataset(data)
   1239             dataset = dataset.redim(**self._redim)
-> 1240         obj = method(x, y)
   1241         obj._dataset = dataset
   1243 if self.crs and self.project:
   1244     # Apply projection before rasterizing

File ~/miniforge3/envs/schism_viz/lib/python3.8/site-packages/hvplot/converter.py:1645, in HoloViewsConverter.line(self, x, y, data)
   1643 def line(self, x=None, y=None, data=None):
   1644     self._error_if_unavailable('line')
-> 1645     return self.chart(Curve, x, y, data)

File ~/miniforge3/envs/schism_viz/lib/python3.8/site-packages/hvplot/converter.py:1609, in HoloViewsConverter.chart(self, element, x, y, data)
   1607 def chart(self, element, x, y, data=None):
   1608     "Helper method for simple x vs. y charts"
-> 1609     data, x, y = self._process_chart_args(data, x, y)
   1610     if x and y and not isinstance(y, (list, tuple)):
   1611         return self.single_chart(element, x, y, data)

File ~/miniforge3/envs/schism_viz/lib/python3.8/site-packages/hvplot/converter.py:1576, in HoloViewsConverter._process_chart_args(self, data, x, y, single_y, categories)
   1573 elif not self.gridded_data:
   1574     data = self._transform_columnar_data(data)
-> 1576 x = self._process_chart_x(data, x, y, single_y, categories=categories)
   1577 y = self._process_chart_y(data, x, y, single_y)
   1579 # sort by date if enabled and x is a date

File ~/miniforge3/envs/schism_viz/lib/python3.8/site-packages/hvplot/converter.py:1553, in HoloViewsConverter._process_chart_x(self, data, x, y, single_y, categories)
   1550     x = xs[0] if len(xs) else None
   1552 if not x and not categories:
-> 1553     raise ValueError('Could not determine what to plot. Set x explicitly')
   1554 return x

ValueError: Could not determine what to plot. Set x explicitly
dwr-psandhu commented 1 year ago

Workaround is the rename index.

maximlt commented 1 year ago

Hi @dwr-psandhu and thanks for this bug report.

Pandas indeed allows to have an index named with an integer value, and probably some other types too. Yet we generally recommend using string types for the index and columns names.

I had a quick look at this issue, there seems to be two problems. First in the following lines when x = 0 the condition is true, because 0 is interpreted as false by Python.

   1552 if not x and not categories:
-> 1553     raise ValueError('Could not determine what to plot. Set x explicitly')

But that wouldn't be enough, as 0 would be passed down to HoloViews as a dimension name, HoloViews would then raise an error as it only accepts string dimension names. We've already had to work around that for Pandas columns, I guess it's an oversight not to have applied the same workaround to the index. So the second part of the fix would I think be to extend the _transform_columnar_data method in the converter.py module to also cast the index names to strings.