Dash Holoviews+Datashader & Datetime axes: y u no work

I have been trying out the new Holoviews integration with Dash as it finally offers a great native solution to use datashader for some of the plots in my dashboard. However, one issue I haven’t found a solution to (despite much googling) is the problem with datetime axes, particularly for Quadmeshes. When I visualize the rasterized quadmesh without a datetime x-axis, it works fine. When I replace the x-axis with datetimes, I always get the following error (no matter what formatting I try) :

Traceback (most recent call last):
  File "MWE.py", line 36, in <module>
    components = to_dash(app,
  File "anaconda3\lib\site-packages\holoviews\plotting\plotly\dash.py", line 369, in to_dash
    plot = PlotlyRenderer.get_plot(hvobj)
  File "anaconda3\lib\site-packages\holoviews\plotting\renderer.py", line 243, in get_plot
    plot.update(init_key)
  File "anaconda3\lib\site-packages\holoviews\plotting\plot.py", line 982, in update
    return self.initialize_plot()
  File "anaconda3\lib\site-packages\holoviews\plotting\plotly\element.py", line 126, in initialize_plot
    fig = self.generate_plot(self.keys[-1], ranges, is_geo=is_geo)
  File "anaconda3\lib\site-packages\holoviews\plotting\plotly\element.py", line 181, in generate_plot
    data = self.get_data(element, ranges, style, is_geo=is_geo)
  File "anaconda3\lib\site-packages\holoviews\plotting\plotly\raster.py", line 44, in get_data
    dx, dy = float(r-l)/nx, float(t-b)/ny
TypeError: float() argument must be a string or a number, not 'datetime.timedelta'

It seems like the combination of dash+rasterize does not like datetime axes, even though they are supported by regular holoviews+dash. I made an MWE to illustrate the issue:


import dash
import dash_html_components as html
import holoviews as hv
from holoviews.plotting.plotly.dash import to_dash
from holoviews.operation.datashader import rasterize
import numpy as np
import pandas as pd

# Normal numeric x-axis (this works when used in hv.QuadMesh)
X = np.logspace(1,5,100)
# Datetime x-axis
X_datetime = pd.date_range(start='1/1/2018', end='1/08/2018',periods=100)

Y = np.linspace(1,100,100)
Z = np.random.randn(100,100)

options = dict(cmap='jet',
               colorbar=True,
               height=600)

figure  = rasterize(hv.QuadMesh((X_datetime, Y, Z)),
                    dynamic=True,
                    width=50,
                    height=50
                    )
figure = figure.opts(**options)

app = dash.Dash(__name__)
components = to_dash(app,
                     [figure],
                     reset_button=True)

app.layout = html.Div(components.children)

if __name__ == "__main__":
    app.run_server(debug=True)

Is the possibility to have datetime axes in a rasterized holoviews chart simply not supported by the Plotly renderer, or am I doing something wrong here?
Thanks in advance!

Has there been any udpdate here, have you been able to solve this? I have the same issue, a simple scatter plot with x axis as datetime fails. A workaround could be to use integers and change the labels to the corresponding datetime, but that’s a smelly workaround

I’m running into this exact issue as well. Has anayone come up with a workaround?

For anyone who runs into this problem in the future, I’ve come up with a workaround. It isn’t perfect because you’ll have to fix how many major ticks you want on the X-axis, and the tick labels aren’t as elegant as what Plotly can do automatically, but this at least gets some datetimes shown on the X-axis.

import dash
from dash import html
import holoviews as hv
from holoviews.plotting.plotly.dash import to_dash
from holoviews.operation.datashader import rasterize
import numpy as np
import pandas as pd

# Normal numeric x-axis (this works when used in hv.QuadMesh)
X = np.logspace(1,5,100)
X_indices = np.linspace(0,99,100)
# Datetime x-axis
X_datetime = pd.date_range(start='1/1/2018', end='1/08/2018',periods=100)

Y = np.linspace(1,100,100)
Z = np.random.randn(100,100)

options = dict(cmap='jet',
               colorbar=True,
               height=600)

figure  = rasterize(hv.QuadMesh((X_indices, Y, Z)),
                    dynamic=True,
                    width=50,
                    height=50
                    )
figure = figure.opts(**options)

app = dash.Dash(__name__)
components = to_dash(app,
                     [figure],
                     reset_button=True)

# replace X-axis indices with datetimes
# first grab the graph out of the list of components
graph = components[0][0]

# update the x-axis tick labels with a fixed number of datetimes, in this case 4 major ticks will be shown
graph.figure["layout"]["xaxis"]["type"] = "datetime"
graph.figure["layout"]["xaxis"]["tickvals"] = np.linspace(X_indices.min(), X_indices.max(), 4)
graph.figure["layout"]["xaxis"]["ticktext"] = pd.date_range(X_datetime.min(), X_datetime.max(), periods=4)

# replace the graph component in the list of components
components[0][0] = graph

app.layout = html.Div(components.children)

if __name__ == "__main__":
    app.run_server(debug=True)

FYI, I reported this bug to Holoviews on Github and they have flagged the issue as a bug in Datashader.
https://github.com/holoviz/holoviews/issues/6089