Dimension Not Found

I am trying to plot two Curves on the same plot, and apply the datashade() method. Here is part of my code:

c = hv.Curve(df, kdims='TIME', vdims='YZF12500')
c2 = hv.Curve(df, kdims='TIME', vdims='YZF12525')
line_overlay = hv.NdOverlay({'first':c, 'second':c2}, kdims='Parameter')
pn.serve(datashade(line_overlay, pixel_ratio=2, line_width=4, aggregator=ds.by('Parameter',
                                                                               ds.count())).opts(width=800))

I based this approach on the Large Data tutorial, where they plot some Curves with datashader.

I receive the following error (at the end of a very extensive traceback):
KeyError: "Dimension('YZF12525') not found."

Any advice on what I’m doing wrong is appreciated!

EDIT:
With some investigation, it appears that Curve “c” is a good Element, and I can inspect it’s dimensions() to show ‘TIME’ and ‘YZF12500’ for example. But the output of datatashade() has “no dimensions”, where dimensions() returns “[ ]”. This is true whether I apply datashade() with all those args and opts, or if I simply run datashade(c). So I assume I’m missing something fundamental about applying that method to a Curve.

EDIT 2:
I think it might be important to put brackets around kdims and vdims in the Curve() instantiations. Also realized that if I provide only one item in the NdOverlay dictionary, instead of two Curves, it plots that one happily. I suspect this may be another instance of datashade() being the root cause, or at least the way I’m using it…

1 Like

Hi @CrashLandonB

Could you please provide a minimum, reproducible example? It helps a lot to quickly understand and be able to reproduce the issue. Thanks.

Sure thing:

The following code works, to plot one Curve:

import holoviews as hv
from holoviews import opts
import datashader as ds
from holoviews.operation.datashader import datashade
import panel as pn
import numpy as np
import pandas as pd

hv.extension('bokeh')
df = pd.DataFrame(np.random.randint(0,100,size=(50000, 2)), columns=['YZF12500', 'YZF12525'])
df.index.name = 'TIME'

# Create curves for each parameter
c = hv.Curve(df, kdims=['TIME'], vdims=['YZF12500'])
c2 = hv.Curve(df, kdims=['TIME'], vdims=['YZF12525'])
line_overlay = hv.NdOverlay({'first': c}, kdims='Parameter')
pn.serve(datashade(line_overlay, pixel_ratio=2, line_width=4, aggregator=ds.by('Parameter',
                                                                               ds.count())).opts(width=800))

However, if you change the line_overlay definition to create an overlay from the dict with two Curves,
line_overlay = hv.NdOverlay({'first': c, 'second': c2}, kdims='Parameter')
the spawned browser window returns a:
500: Internal Server Error
and the console returns the KeyError:
KeyError: "Dimension('YZF12525') not found."

Hi @CrashLandonB ,

To continue down the same path I think your missing a loop function for when multiple curves come into play (i’m not sure why passing as dict fails, because data example isn’t so large you can plot your multi line overlay before data-shading, very last line when datashader comes into the mix it fails)… see for examples https://datashader.org/user_guide/Timeseries.html

import holoviews as hv
from holoviews import opts
import datashader as ds
from holoviews.operation.datashader import datashade, rasterize
import panel as pn
import numpy as np
import pandas as pd

hv.extension('bokeh')
df = pd.DataFrame(np.random.randint(0,100,size=(50000, 2)), columns=['YZF12500', 'YZF12525'])
df.index.name = 'TIME'
df.reset_index(inplace=True) #from the linked tutorial example works with index reset
cols=['YZF12500','YZF12525'] #list for the loop

# Create curves for each parameter
curve1 = hv.Curve(df, kdims=['TIME'], vdims=['YZF12500'])
curve2 = hv.Curve(df, kdims=['TIME'], vdims=['YZF12525'])

#loop function here to cycle through list of colums provided
ndoverlay = hv.NdOverlay({c:hv.Curve((df['TIME'], df[c]), kdims=['TIME'], vdims=['Value']) for c in cols})

pn.serve(datashade(ndoverlay,cmap=["lightblue", "red"])) #removed the rest as didn't spend time on further introduced error of x must be real.. added a cmap to give curves distinction, datashade turned both curves blue without cmap

Alternatively i guess you could work with single curves and use the holoviews * operator to overlay the individual curves onto single graph and rasterize for auto colour mapping and keeping colour bar that you kind of lose with datashader.

Hope of some help

Thanks Carl

Your suggestion with a little tweaking helped me figure it out. The following is close to what I ended up with:

import holoviews as hv
import datashader as ds
from holoviews.operation.datashader import datashade
import panel as pn
import numpy as np
import pandas as pd

import trahdflib as th

hv.extension('bokeh')

# Alternative random dataframe creation
df = pd.DataFrame(np.random.randint(0, 100, size=(50000, 2)), columns=['YZF12500', 'YZF12525'])

# Create curves for each parameter
c = hv.Curve((df.index, df['YZF12500']), kdims=['Time'], vdims=['Value'])
c2 = hv.Curve((df.index, df['YZF12525']), kdims=['Time'], vdims=['Value'])

line_overlay = hv.NdOverlay({'YZF12500': c, 'YZF12525': c2}, kdims='k')
pn.serve(datashade(line_overlay, pixel_ratio=2, line_width=4, aggregator=ds.by('k', ds.count())).opts(width=800)) # works
2 Likes