面板和全息视图之间的交互
Interaction between panel and holoviews
我正在使用 holoviews
和 panel
开发一个小部件 - 它包括读取 pandas.dataFrame
并为每一列显示一条曲线。我需要的交互是能够从图中提取 add/remove 列。
在我的实际用例中,列太多,所以我无法利用 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, 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()
为方便起见,我将代码在线存储为要点上的笔记本:
我的问题是当我定义 @pn.depends method
时 holoviews
和 panel
在单元格 #7
(在笔记本中)之间的交互 - 我得到的唯一方法到目前为止,它的工作原理是在每次交互时“重新加载”数据……(cell_out:[#21]
,第 [#3]
行,在 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 笔记本中制作代码原型的方式。 运行 时出现奇怪的行为
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
我正在使用 holoviews
和 panel
开发一个小部件 - 它包括读取 pandas.dataFrame
并为每一列显示一条曲线。我需要的交互是能够从图中提取 add/remove 列。
在我的实际用例中,列太多,所以我无法利用 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, 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()
为方便起见,我将代码在线存储为要点上的笔记本:
我的问题是当我定义 @pn.depends method
时 holoviews
和 panel
在单元格 #7
(在笔记本中)之间的交互 - 我得到的唯一方法到目前为止,它的工作原理是在每次交互时“重新加载”数据……(cell_out:[#21]
,第 [#3]
行,在 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 笔记本中制作代码原型的方式。 运行 时出现奇怪的行为
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