What is the best way to change the widget type in

2020-04-07 04:58发布

问题:

Using the functionality in pyviz, it's easy to generate an hvplot/panel interactive dashboard for a gridded xarray dataset, like this air temperature data example:

import xarray as xr
import hvplot.xarray
import panel as pn

airtemps = xr.tutorial.load_dataset('air_temperature')
atemp = airtemps.air[:10,:,:]
mesh = atemp.hvplot(groupby='time')
row = pn.Row(mesh)
display(row)

which automatically creates a slider for the time dimension:

If I take a look at the object created:

print(row)

I can see that a DiscreteSlider widget was created:

Row
    [0] Row
        [0] HoloViews(DynamicMap)
        [1] WidgetBox
            [0] DiscreteSlider(name='Time', options=OrderedDict([('2013-01-01 ...]), value=numpy.datetime64('2013-01-...)

What is the best way to replace the DiscreteSlider widget with a drop down menu Select widget?

回答1:

To understand how to customize the display output of different types you have to understand how panel transform the objects that you give it into the objects that you see when displaying the pprint output. Specifically, internally panel will call the pn.panel function which tries to find the most appropriate Pane object to render what you gave it. In this case that is the HoloViews pane which is responsible for generating the widgets and for rendering the actual plot. In other words this code:

row = pn.Row(mesh)

is actually equivalent to:

row = pn.Row(pn.panel(mesh))

which in turn is equivalent to:

row = pn.Row(pn.holoviews.HoloViews(mesh).layout)

Once you are at the level of the actual Pane used to render the object you will be able to see the parameters available to customize the visual representation of the object. In the case of the HoloViews pane it offers a widgets parameter which allows supplying widget classes or instances as overrides for each of the dimensions in the object you are displaying. In your case you therefore want to do something like this:

pn.holoviews.HoloViews(mesh, widgets={'time': pn.widgets.Select}).layout

or less explicitly:

pn.panel(mesh, widgets={'time': pn.widgets.Select})