holoviz / holoviews

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

Overlaying datashader legends on timeseries plots #2401

Open nr7s opened 6 years ago

nr7s commented 6 years ago

Is there a way to overlay a legend plot like the ones from this User Guide - Multidimensional plots section. What happens right now is that when you overlay the legend on the timeseries plot you lose the automatic handling of the datetime x axis

I thought it was because the points being used for the column were 0,0 and maybe passing them as the first point of the curve I'm trying to plot would work but I get the following error:

DataError: None of the available storage backends were able to support the supplied data format.

I used something like this

def multitimeplot(pts, y):    
    lines = {i: hv.Curve(pts_d[pts[i]], 'timestamp',  y) for i in range(len(pts))}
    overlay = dynspread(datashade(hv.NdOverlay(lines, kdims='k'), aggregator=ds.count_cat('k')))

    color_key = list(enumerate(Sets1to3[0:len(pts)]))
    color_points = hv.NdOverlay({pts[k]: hv.Points(list(pts_d[pts[k]].head(1)[['timestamp', y]].values[0]), 
                                                  label=str(pts[k])).opts(style=dict(color=v)) for k, v in color_key})

    return color_points * overlay                                       
jlstevens commented 6 years ago

@philippjfr @jbednar Any thoughts on this?

jbednar commented 6 years ago

We really do need to get some proper legend and colorbar support for datashader plots; it's way overdue (like so many other things...). But I think you're on the right track here; the fake points that are overlaid need to be valid points for this plot. Maybe just debug it by trying to overlay a single Point somewhere clearly visible; once that works the NdOverlay of points should be a tiny step from there.

danjjl commented 6 years ago

I got this to work with the following code:

hvObj *= hv.NdOverlay({k: hv.Scatter(data_df.head(1), kdims='time', vdims=y, label=str(k)).opts(
    style=dict(color=cmap[i])) for i, k in enumerate(signal_names)})

1) Used Scatter in place of Points 2) Selected the first row of my dataset to provide an existing point

This is based on my data structure where