Open asmith26 opened 5 years ago
Bokeh legends are already clickable to mute/unmute specific traces in some cases, but for that to work in general for map tiles, etc. would currently require creating a corresponding Panel widget that sets the alpha property of each item and selects which map tile provider to use. But it does seem like there could be a custom Bokeh tool that handles this common use case, which would be nice to have...
This would be really awesome to have!
I'm thinking of having a go at this.
I feel this could be implemented as a bokeh tool:
(df.hvplot.points(x="x", y="y") * df.hvplot.line(x="x", y="y")).opts(tools=["layers_control"])
potentially creating a button (e.g. p1, p2 could denote "plot1", "plot2") for each overlay element (I think this is called a glyph is bokeh terminology):
Or as a holoviews option:
(df.hvplot.points(x="x", y="y") * df.hvplot.line(x="x", y="y")).opts(show_layers_control=True)
This could potentially be added to a plot like a legend is (also similar to the image above)
Any help appreciated (mentioning @bryevdv and @philippjfr in case they kindly have any advice), many thanks!
I'm more familiar with Holoview/HoloViz, so thought I try some code:
import pandas as pd
import panel as pn
import param as pm
import hvplot.pandas
df = pd.DataFrame({
"x": [1,2,3],
"y": [1,2,3],
})
show_plot = pn.widgets.Checkbox()
plot = df.hvplot.points(x="x", y="y")
@pn.depends(show_plot.param.value)
def get_plot(value):
return plot.opts(alpha=value)
pn.Column(show_plot, get_plot)
This works, but I think it is generating a new plot (thus may be slow for big or datashaded data). To get around this, following the approach of the NYC taxi demo:
plot = df.hvplot.points(x="x", y="y")
class LayersControl(pm.Parameterized):
# show_plot = pm.Boolean(True) # "couldn't get working"
show_plot = pm.Magnitude(default=1.0)
def viewable(self, **kwargs):
return plot.apply.opts(alpha=self.param.show_plot)
lc = LayersControl()
pn.Column(lc.param, lc.viewable())
Not sure if this is the correct approach, or how it would integrate with the library code.
I've recently established this seems to work quite well (allows you to turn layers on and off using the legend):
# gdf := GeoPandas GeoDataFrame
gdf.hvplot(.. label='Some Layer', muted_alpha=0.001) * gdf.hvplot(.. label='Another Layer', muted_alpha=0.001)
I like this suggestion and I particularly like the bokeh tools idea...
Bumping this as a definite nice-to-have standard feature. 😀
LayerGroups/ Selector API is really one of the only things still pulling me back towards ipyleaflet from holoviz in my project.
I think this is related: https://github.com/holoviz/panel/issues/5115
import panel as pn
import geoviews as gv
gv.extension("bokeh")
pn.extension()
sliders = pn.Column()
overlay = gv.Overlay().opts(width=500, height=500)
for tile_source in gv.tile_sources.tile_sources:
slider = pn.widgets.IntSlider(
name=tile_source,
value=0,
start=0,
stop=10,
step=1,
)
if tile_source == "OSM":
slider.value = 1
sliders.append(slider)
overlay *= (
gv.tile_sources.tile_sources[tile_source]
.apply.opts(alpha=slider.param.value)
.opts(global_extent=True)
)
pn.Row(sliders, overlay).servable()
This kind of works, but it's clunky. I initially tried using toggle, but alpha
doesn't accept booleans and I'm not sure if I can use hv.dim
or something to convert it to a float value.
https://github.com/holoviz/holoviews/assets/15331990/f819fb1a-dbb1-4bc1-a262-9a5f01de7a07
Got the slider to work with jslink too
import panel as pn
import geoviews as gv
import xarray as xr
gv.extension("bokeh")
pn.extension()
ds = xr.tutorial.open_dataset('air_temperature')
slider = pn.widgets.FloatSlider(name="alpha", start=0, end=1, value=0.5)
plot = gv.tile_sources.CartoLight()
slider.jslink(plot, value="glyph_renderer.alpha")
pn.Column(slider, plot).servable()
I work a lot with Geospatial data, and having the ability to quickly show/hide different HoloViews objects (e.g. a satelite tif image and another hv object of e.g. air temperature) would be very useful.
A similiar example is: https://rstudio.github.io/leaflet/showhide.html
Does this functionality already exist? I'm not that familiar with HoloViews internals, but I feel this could work something like:
Many thanks for any help (and many awesome viz libraries!)