面板和全息视图之间的交互

问题描述

我正在使用 holoviewspanel 开发一个小部件 - 它包括读取 pandas.dataFrame 并为每列显示一条曲线。我需要的交互是能够从图中添加/删除列。 在我的实际用例中,列太多,因此我无法利用 bokeh+holoviews 已经提供的交互式图例。

我做了一个小例子,说明 ''' 有点作用 ''' 但我可能做错了,因为每次与 panel.widgets.MultiChoice 交互时我都会重新加载绘图的数据(其中显然是错误的)


import holoviews as hv
import numpy as np
import pandas as pd
import colorcet as cc
import panel as pn

pn.extension()
hv.extension("bokeh")

# generate some data
def get_data():
    data = {
        "1998": np.random.rand(365),"1999": np.random.rand(365),"2000": np.random.rand(365),"2002": np.random.rand(365),"2003": np.random.rand(365),}
    df = pd.DataFrame(data,index=range(0,365))
    return df

# utility to help me placing the month label around the 2nd week of each month

def split_list(a,n):
    k,m = divmod(len(a),n)
    return list(
        list(a[i * k + min(i,m) : (i + 1) * k + min(i + 1,m)]) for i in range(n)
    )


def get_ticks(df,pos):
    splitter = split_list(df.index,12)
    months = [
        "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",]
    xticks_map = [i for i in zip([splitter[i][pos] for i in range(0,12)],months)]
    return xticks_map

# plotting method

def get_mplot(df,cols=None):
    if cols:
        df = df[cols]
    if len(df.columns) == 0:
        print("No coumns selected")
        return None
    grid_style = {
        "grid_line_color": "black","grid_line_width": 1.1,"minor_ygrid_line_color": "lightgray","minor_xgrid_line_color": "lightgray","xgrid_line_dash": [4,4],}
    colors = cc.glasbey_light[: len(list(df.columns))]
    xticks_map = get_ticks(df,15)
    multi_curve = [
        hv.Curve((df.index,df[v]),label=str(v)).opts(
            xticks=xticks_map,xrotation=45,width=900,height=400,line_color=colors[i],gridstyle=grid_style,show_grid=True,)
        for i,v in enumerate(df)
    ]
    mplot = hv.Overlay(multi_curve)
    return mplot


# get the data
df = get_data()

# create a multi-choice widget

years = pn.widgets.MultiChoice(
    name="Years",options=list(df.columns),margin=(0,20,0)
)

# bind plot and multi-choice

@pn.depends(years)
def get_plot(years):
    df = get_data()
    if years:
        df = df[years]
    mplot = get_mplot(df,years)
    return mplot


pn.Column("Plot!",get_plot,pn.Row(years),width_policy="max").servable()

为方便起见,我将代码作为笔记本在线存储在一个要点上:

notebook

我的问题是当我定义 holoviews 时,panel#7 在单元格 @pn.depends method(在笔记本中)之间的交互 ​​- 这是我得到它的唯一方法到目前为止的工作是在每次交互时“重新加载”数据……(cell_out: [#21],line [#3],in df = get_data() )如果数据开始加载,这显然会减慢整个应用程序的速度增加

本质上,我需要一种与绘图组件交互的方法,而不是在每次交互时重新执行绘图。在普通的散景中,我会编写一个连接到情节的处理程序,但这是我的理解,在 holoviews+panel 中(因为它们是建立在散景之上的一组更高级别的库)应该是实现相同目标的更简单方法

您是否有任何关于如何避免重新加载数据集的提示

解决方法

我认为您只需要先加载数据而不是覆盖数据框,例如:

df = get_data()

@pn.depends(years)
def get_plot(years):
    if years:
        df1 = df[years]
    mplot = get_mplot(df1,years)
    return mplot
,

建立在@rich-signell 之上,当从多选小部件中删除所有条目时,这也将起作用:

@pn.depends(years)
def get_plot(years):
    if years:
        df1 = df[years]
        mplot = get_mplot(df1,years)
    else:
        mplot = get_mplot(df)
    return mplot

然而,我面临的问题是由于我在 jupyter notebook 中对代码进行原型设计的方式。运行时有一个奇怪的行为 holoviews+panel 在 jupyter 笔记本中。我能够使用以下版本在两个不同的 jupyter 服务器上复制它

Jupyterlab,holoviews,panel

'2.2.9','1.14.0','0.11.0a3.post2+g5aa0c91'
'3.0.7','1.14.2.post2+gd235b1cb0','0.10.3'

问题是应用到 get_plot() 方法的更改,用 @pn.depends 修饰 - 直到笔记本内核重新启动时才被 panel 小部件接收,因此任何尝试更改代码(也是可行的解决方案)无效并让我感到困惑。

试图在此录音中显示问题 https://gist.github.com/epifanio/6c9827f9163de359130102a29d7f3079

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...