4

在基于 xArray 数据使用 HoloViews 创建绘图(QuadMesh)时,任何缺失的维度都会自动创建滑块等小部件,以方便数据探索。例如:

hv_ds = hv.Dataset(data)    
plot = hv_ds.to(hv.QuadMesh, kdims=["lon", "lat"], vdims="depth")

由于数据包含 12 个月的数据,HoloViews 将创建基于 lon 和 lat 的 QuadMesh,使用深度作为值,然后提供一个滑块小部件来选择月份。它将把它全部包装在一个 HoloMap 中,如下所示:

HoloMap containing 12 items of type QuadMesh
--------------------------------------------

Key Dimensions: 
     month: 1.0...12.0 
Deep Dimensions: 
     lon: -280.0...80.0 
     lat: -78.0...-44.6 
     depth: 3.5...4796.6 

生成的图

我想检索“月滑块小部件”的值来更新另一个绘图,但我找不到访问它的方法。没有plot.get_widget_value()或类似的东西。有什么想法我可以得到一个指针或它的处理程序吗?

4

2 回答 2

1

当您创建这样的小部件 + 绘图时,我不知道如何获取当前值。也许别人知道。

但我确实知道如何在使用面板创建小部件 + 绘图时获取当前选定的值,如下例所示。如果你这样做,你可以用它your_selection_widget.value来获取当前选定的值:

# import libraries
import numpy as np
import pandas as pd

import hvplot
import hvplot.pandas

import holoviews as hv
hv.extension('bokeh', logo=False)

import panel as pn


# create sample data
df = pd.DataFrame({
    'col1': np.random.rand(30),
    'col2': np.random.normal(size=30),
    'category_col': np.random.choice(['category1', 'category2'], size=30)
})

# create widget to select category
category = pn.widgets.Select(options=['category1', 'category2'])

# function that returns a plot depending on the category selected
@pn.depends(category)
def get_plot(category):
    df_selected = df[df['category_col'] == category]
    plot = df_selected.hvplot.scatter(x='col1', y='col2')
    return plot

# show dashboard with selection widget and dynamic plot
pn.Column(
    pn.Row(category),
    get_plot,
)

# get value of current selected category
category.value

您可以在此处找到有关如何创建这样的交互式仪表板的更多信息:
https ://panel.pyviz.org/gallery/apis/stocks_hvplot.html#gallery-stocks-hvplot

于 2019-11-27T18:16:09.370 回答
1

[很久以后......发布以防对其他人有价值]

这是一种可行的方法,但我想有更简单的方法......

## imports
import pandas as pd
import numpy as np
import xarray as xr

import hvplot.xarray
import panel as pn

## generate an xr.DataArray
start_date = '2021-01-01'
time = pd.date_range(start=start_date, periods=12, freq='M')
x,y = np.ogrid[0:512, 0:512]
data = np.random.randn(time.size, x.size, y.size)
coords = dict(time=time, x=x.ravel(), y=y.ravel())
space_time_xr = xr.DataArray(data, coords=coords, dims=list(coords), name='space_time')

选项 A:hvPlot --> 面板

## use hvplot to implicitly generate the widget -- there's an alternative 
space_time_hv = space_time_xr.hvplot(x='x', y='y')

## use panel to access the slider
space_time_pn = pn.panel(space_time_hv)

## a pointer to the slider widget
time_slider_pnw = space_time_pn[1][0][0]

## present the viz+widget
space_time_pn

选项 A 截图

选项 B:使用.interactive API

需要hvplot version >= 0.7

## use .interactive API to generate the widget
space_time_pnw = space_time_xr.interactive.sel(time=pn.widgets.DiscreteSlider).hvplot()

## a pointer to the slider widget
time_slider_pnw = space_time_pnw.widgets().objects[0]

## present the viz+widget
space_time_pnw

玩滑块... 然后可以读出滑块的当前值:

## get slider current value
current_pnw_value = time_slider_pnw.value

## print the value
print(f'{current_pnw_value}')

对于正在更改小部件状态的“实时”更新,可以检查,例如 面板#Links

(选项 C).interactive + 链接示例:标题根据小部件状态更新

## use interactive API to generate the widget
time_slider_pnw = pn.widgets.DiscreteSlider(name='time',options=space_time_xr.time.to_series().to_dict())
space_time_pn = space_time_xr.interactive.sel(time=time_slider_pnw).hvplot()

## dynamics markdown
time_md = pn.pane.Markdown(f'## {time_slider_pnw.value:%Y-%m-%d}')

def callback(target, event):
    target.object = f'## {event.new:%Y-%m-%d}'
    
## link
time_slider_pnw.link(time_md, callbacks={'value' : callback} )

## present the time slider value
pn.Column(time_md, space_time_pn.panel(), space_time_pn.widgets())

选项 C .interactive + 链接截图

使用版本:

Python version       : 3.7.10

numpy : 1.20.2
xarray: 0.18.0
pandas: 1.2.4

hvplot    : 0.7.1
panel     : 0.11.3
holoviews : 1.14.3
bokeh     : 2.3.1
jupyterlab: 3.0.14
于 2021-05-11T02:18:29.710 回答