holoviz / holoviews

With Holoviews, your data visualizes itself.
https://holoviews.org
BSD 3-Clause "New" or "Revised" License
2.66k stars 396 forks source link

Exceptions raised when trying to create stacked bar chart with continous x-axis. #6302

Closed MarcSkovMadsen closed 1 day ago

MarcSkovMadsen commented 6 days ago

I'm trying to create a stacked bar chat with a continuous x-axis. No matter what i do it raises exceptions or does not produce what I need.

What I wished worked

datetime x-axis, boolean y-axis.

from datetime import datetime

import holoviews as hv
import hvplot.pandas
import pandas as pd
import panel as pn

pn.extension()

data = pd.DataFrame({
    "notationtime": ["2024-01-01", "2024-01-01", "2024-01-02", "2024-01-02"],
    "is_valid": [False, True, False, True],
    "count": [3,1,2,2]
})
data["notationtime"]=pd.to_datetime(data["notationtime"])
pn.panel(data.hvplot.bar(x="notationtime", y="count", by="is_valid", stacked=True)).servable()
ValueError: failed to validate CategoricalColorMapper(id='p1241', ...).factors: expected an element of either Seq(String), Seq(Tuple(String, String)) or Seq(Tuple(String, String, String)), got [False, True]

Ok. I convert boolean y-values to strings

from datetime import datetime

import holoviews as hv
import hvplot.pandas
import pandas as pd
import panel as pn

pn.extension()

data = pd.DataFrame({
    "notationtime": ["2024-01-01", "2024-01-01", "2024-01-02", "2024-01-02"],
    "is_valid": [False, True, False, True],
    "count": [3,1,2,2]
})
data["notationtime"]=pd.to_datetime(data["notationtime"])
data["is_valid"]=data["is_valid"].map({True: "Valid", False: "Invalid"})
pn.panel(data.hvplot.bar(x="notationtime", y="count", by="is_valid", stacked=True)).servable()

It just shows 1 bar in stead of two. Its the same if increase the number of notationtimes.

image

date32[arrow] type is not supported either

My original notationtime was date32[arrow]. Does not seem to be supported either.

from datetime import datetime

import holoviews as hv
import hvplot.pandas
import pandas as pd
import panel as pn

pn.extension()

data = pd.DataFrame({
    "notationtime": ["2024-01-01", "2024-01-01", "2024-01-02", "2024-01-02"],
    "is_valid": [False, True, False, True],
    "count": [3,1,2,2]
})
data["notationtime"]=data["notationtime"].astype("date32[pyarrow]")
data["is_valid"]=data["is_valid"].map({True: "Valid", False: "Invalid"})
pn.panel(data.hvplot.bar(x="notationtime", y="count", by="is_valid", stacked=True)).servable()
TypeError: unsupported operand type(s) for /: 'float' and 'datetime.timedelta'

Traceback (most recent call last):
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/io/handlers.py", line 389, in run
    exec(self._code, module.__dict__)
  File "/home/jovyan/repos/mt-pm-reporting/script.py", line 17, in <module>
    pn.panel(data.hvplot.bar(x="notationtime", y="count", by="is_valid", stacked=True)).servable()
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/viewable.py", line 394, in servable
    self.server_doc(title=title, location=location) # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/viewable.py", line 1001, in server_doc
    model = self.get_root(doc)
            ^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/pane/base.py", line 420, in get_root
    root_view, root = self._get_root_model(doc, comm, preprocess)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/pane/base.py", line 349, in _get_root_model
    root = self.layout._get_model(doc, comm=comm)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/layout/base.py", line 185, in _get_model
    objects, _ = self._get_objects(model, [], doc, root, comm)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/layout/base.py", line 167, in _get_objects
    child = pane._get_model(doc, root, model, comm)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/pane/holoviews.py", line 429, in _get_model
    plot = self._render(doc, comm, root)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/pane/holoviews.py", line 525, in _render
    return renderer.get_plot(self.object, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/holoviews/plotting/bokeh/renderer.py", line 68, in get_plot
    plot = super().get_plot(obj, doc, renderer, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/holoviews/plotting/renderer.py", line 239, in get_plot
    plot.update(init_key)
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/holoviews/plotting/plot.py", line 956, in update
    return self.initialize_plot()
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/holoviews/plotting/bokeh/element.py", line 2130, in initialize_plot
    self._init_glyphs(plot, element, ranges, source)
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/holoviews/plotting/bokeh/element.py", line 2030, in _init_glyphs
    data, mapping, style = self.get_data(element, ranges, style)
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/holoviews/plotting/bokeh/chart.py", line 930, in get_data
    width /= xdiff
TypeError: unsupported operand type(s) for /: 'float' and 'datetime.timedelta'
hoxbro commented 4 days ago

datetime x-axis

The issue looks like a duplicate of https://github.com/holoviz/holoviews/issues/6288

boolean y-axis.

Should be simple to implement.

date32[arrow]

I'm not surprised that arrow dtypes are currently not working. I would love to spend some time on this, but I don't have the time right now. A simple way for now could be to convert it to numpy dtypes, but I haven't looked into how much work is needed.

MarcSkovMadsen commented 4 days ago

convert to numpy dtypes is a simple as pd.to_datetime. But it will convert to datetime64. I'm not aware numpy has a date only data type.

hoxbro commented 4 days ago

There is datetime64[D], but I'm unsure how widely used it is.

hoxbro commented 1 day ago

I have opened https://github.com/holoviz/holoviews/issues/6308 for improving dtype support for pyarrow.

I will close this issue with https://github.com/holoviz/holoviews/pull/6304, as the other problems you are seeing now have their own issues. If you disagree with my assessment, please open a new issue.