-
-
Notifications
You must be signed in to change notification settings - Fork 402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Drilldown support #5884
Comments
Here's an example using hvplot / holoviews. I had to make some internal changes here https://github.com/holoviz/holoviews/pull/5885/files And I was able to create an example: import holoviews as hv
from bokeh.plotting import figure
from bokeh.models.tools import HoverTool
from bokeh.models import RendererGroup
from bokeh.models.dom import (
Div,
Index,
Span,
Styles,
Template,
ValueRef,
ToggleGroup,
)
hv.extension("bokeh")
def timeseries():
plot = figure(
width=150,
height=75,
toolbar_location=None,
x_axis_label="Hours Ago",
y_axis_label="Temperature (F)",
)
groups = []
for station, station_df in df.groupby("station"):
hours = (station_df["valid"].iloc[0] - station_df["valid"]).dt.total_seconds() / 3600
tmpf = station_df["tmpf"]
group = RendererGroup(visible=False)
groups.append(group)
glyph = plot.line(x=hours, y=tmpf, line_width=2, line_color="black")
glyph.group = group
return plot, groups
def tooltips():
plot, groups = timeseries()
style = Styles(
display="grid",
grid_template_columns="auto auto",
column_gap="10px",
)
grid = Div(style=style)
grid.children = [
Span(),
Span(children=["#", Index()]),
"Station",
Span(style=dict(font_weight="bold"), children=[ValueRef(field="station")]),
"Longitude", ValueRef(field="lon"),
"Latitude", ValueRef(field="lat"),
]
return Template(children=[grid, plot], actions=[ToggleGroup(groups=groups)])
import hvplot.pandas
import pandas as pd
df = pd.read_csv(
"https://mesonet.agron.iastate.edu/cgi-bin/request/asos.py?station=SEA&station=BFI&data=tmpf&year1=2023&month1=9&day1=11&year2=2023&month2=9&day2=12&tz=Etc%2FUTC&format=onlycomma&latlon=yes&elev=no&missing=empty&trace=0.0001&direct=no&report_type=3&report_type=4",
index_col="valid",
parse_dates=True,
).reset_index()
df.head()
hover = HoverTool(tooltips=tooltips())
df.hvplot.points(
"lon", "lat", width=500, height=400, tools=[hover], hover_cols=["station"], tiles=True, geo=True
) However, a few unresolved issues:
This works for hovering only one point, but upon hovering on a second point, it displays an empty plot. import holoviews as hv
from bokeh.plotting import figure
from bokeh.models.tools import HoverTool
from bokeh.models import RendererGroup
from bokeh.models.dom import (
Div,
Index,
Span,
Styles,
Template,
ValueRef,
ToggleGroup,
)
hv.extension("bokeh")
def timeseries():
plot = figure(
width=150,
height=75,
toolbar_location=None,
x_axis_label="Hours Ago",
y_axis_label="Temperature (F)",
)
groups = []
for station, station_df in df.groupby("station"):
station_df["hours_ago"] = (station_df["valid"].iloc[0] - station_df["valid"]).dt.total_seconds() / 3600
group = RendererGroup(visible=False)
groups.append(group)
glyph = hv.render(station_df.hvplot(x="hours_ago", y="tmpf", visible=False)).renderers[0]
plot.renderers.append(glyph)
glyph.group = group
return plot, groups
def tooltips():
plot, groups = timeseries()
style = Styles(
display="grid",
grid_template_columns="auto auto",
column_gap="10px",
)
grid = Div(style=style)
grid.children = [
Span(),
Span(children=["#", Index()]),
"Station",
Span(style=dict(font_weight="bold"), children=[ValueRef(field="station")]),
"Longitude", ValueRef(field="lon"),
"Latitude", ValueRef(field="lat"),
]
return Template(children=[grid, plot], actions=[ToggleGroup(groups=groups)])
import hvplot.pandas
import pandas as pd
df = pd.read_csv(
"https://mesonet.agron.iastate.edu/cgi-bin/request/asos.py?station=SEA&station=BFI&data=tmpf&year1=2023&month1=9&day1=11&year2=2023&month2=9&day2=12&tz=Etc%2FUTC&format=onlycomma&latlon=yes&elev=no&missing=empty&trace=0.0001&direct=no&report_type=3&report_type=4",
index_col="valid",
parse_dates=True,
).reset_index()
df.head()
hover = HoverTool(tooltips=tooltips())
df.hvplot.points(
"lon", "lat", width=500, height=400, tools=[hover], hover_cols=["station"], tiles=True, geo=True
) |
Thanks for opening this issue @jbednar, that was on my TODO list for a while but never got to it. The ability for Bokeh to embed a real plot in a tooltip is interesting. The only problem I see starting with that is that I don't imagine you'd embed yet another plot in the tooltip plot (if that's even possible), while if we are to generalize drilldown I guess we don't want to be limited to drilling down to 1 level but to as many levels as required. |
For now, I think it'd still be immensely useful if there's a convenient/easy way to add plots to the tooltip, but I agree that drilling down would be also very good; I imagine that would take a lot more work though. |
That's funny! At the same time I filed this issue, it reminded me that I needed to chase you about filing whatever issue we had discussed you filing a few weeks ago, so I wrote that down too. I guess "drilldown" was that issue, so I can cross off the chasing task! :-) If you have any notes from our discussion of it at that time, please add them here.
Interesting idea; basically like a browser tab: Click on one point in a plot to bring up a drilldown plot, then click on a point in that plot to drill down further, and so on. Could be implemented and might be useful, but I'm not asking for that! I imagine people would quickly lose track of what they are doing if we keep spawning popups like that. Instead, I was expecting multiple-level drilldown to work more left to right in a layout, not using hover but instead controlling a plot on the right, then clicking on that plot would control a plot to the right of that or below it, etc. That's what I more often see, anyway; hover is for a streamlined simpler case. |
Oh I didn't mean that we should implement multiple-level drill-down with popups. Instead I tried to say that starting with the plot embedded in a tooltip approach may not be the right one to design the drill-down API as it's hard to see how more than 1 level can be of any use. I also expect multiple-level drilldown to work more in a layout, and hopefully more in a Panel layout than in the less flexible HoloViews layout.
In that discussion you shared with me a report that linked to PRs that implemented linked selections in HoloVIews. The description was stating "allow creating new plots based on a selection" and you were wondering whether that was made possible in #4547. Maybe @philippjfr knows better? :)
You also shared some notes taken from a discussion with you and Philipp I believe, from some years ago.
And you stated the following goal:
|
Right; I think we are in agreement about that. But your dismissal of multi-level popups made me at least consider that possibility, which I had not previously. :-) Ok, thanks for keeping those notes; I had now indeed lost track of all that! Sounds like it captures what we've been thinking about. |
Another relevant drilldown example we have already (examples.holoviz.org/landsat): |
And showing Tap vs. hover comparison, from https://github.com/nasa/EMIT-Data-Resources/blob/main/python/tutorials/Exploring_EMIT_L2A_Reflectance.ipynb: |
Just wanted to share this additional resource here (using CustomJSHover to access Python dict values) |
(I could have sworn we had a several-year-old issue about this, but if so I can't find it!)
From my observations, many of what people consider "custom" dashboards are really just trying to show how multiple dimensions of data relate to each other, given the limitations of a 2D computer screen. Linked selections addresses some of the issues, letting you put up various plots of q vs t, h vs g, g vs w, and relate any given data points to the ones shown in other plots, so that you can see how the various quantities that can be measured correlate or distinguish different samples. Many applications of linked selections would have previously had to be complex logic implemented just for that dashboard, and instead the existing linked selections support can simply implement the general notion of linking related data across separate plots once and for all.
The concept of "drilldown" covers another huge swath of "custom" functionality, and I think that if we can provide general drilldown support in HoloViews, we can vastly reduce the complexity of most of the more-ambitious dashboards that people try to build in Panel. With drilldown, usually a given plot shows some aggregated quantity or some subset of dimensions, and the user selects a particular point, manifold (e.g. a line on an image plot), or selection, and a separate plot is then brought up or updated to show unaggregated data or data from different dimensions. E.g. clicking on a location in a map plot could show a curve of some variable at that location over time, or (as in our LANDSAT example) clicking on an RGB pixel can show the full hyperspectral spectrum of the measurements at that pixel across many different frequency bands.
HoloViz developers have discussed drilldown in the context of many different projects over the years, but we have never properly addressed the topic. Sure, Streams make it relatively easy to set up interactive behavior that connects different plots, but Streams are at a much lower level than I am envisioning, because they require some fairly specific plumbing to connect multiple plots. Maybe Streams are as good as it gets, and if so then we need some detailed examples showing how to solve various drilldown situations. But I think we can do much better than that, with generic support for drilldown where we define one of a few supported types of selection, define what the target is (hovering plot, popup plot, plot updated adjacent to the main one, etc.), and connect everything up in a straightforward way.
E.g. given a plot X and a plot Y, I want something that lets me define some selection on X, map something about that selection to Y, and then either display Y or update it if it is already displayed.
Bokeh's hover support is a good initial target: bokeh/bokeh#13375
Can we make it almost as easy to specify such a hovering plot as it is to lay two Elements or Overlays out, side by side? How can we define the connection between those two plots in a general way?
That one goes by points, but by lines is also really useful, providing a cross section on the right sampled across an additional depth dimension for the two lines drawn on the left:
https://earthsim.holoviz.org/user_guide/Analyzing_Meshes.html
There are many, many more examples that can be added here, and I think supporting easy drill down will provide power to ordinary people that really exploits and demonstrates the value of the HoloViews approach.
The text was updated successfully, but these errors were encountered: