我有一个 Altair 图表,希望通过以下方式使其具有交互性。当我单击数据点时,我希望通过其 CLI 启动应用程序,并将数据点的属性作为启动命令的参数提供。我的理解是,使用 Altair 5.3.0 中引入的新 JupyterChart 类应该可以实现这一点 - 请参阅示例 here。然而,按照这个例子,当我尝试通过在观察者回调中调用
subprocess.Popen
来运行我的应用程序时,什么也没有发生。我做错了什么?
这是 MWE:
import altair as alt
import pandas as pd
import subprocess
def on_click(change):
sel = change.new.value[0]
x_sel = df.iloc[sel]["x"]
p = subprocess.Popen(["echo", f"'{x_sel}'"])
df = pd.DataFrame({"x": [1,2], "y": [1,1]})
brush = alt.selection_point("brush")
jchart = alt.JupyterChart(
alt.Chart(df).mark_point(filled=True, size=100, stroke="black").encode(
x=alt.X("x:Q").scale(domain=[0,3]),
y=alt.Y("y:Q").scale(domain=[0,2]),
color=alt.Color("x:Q").legend(None)
)
)
jchart.selections.observe(on_click, ["brush"])
jchart
这是我的环境信息:
- python 3.11.9
- altair 5.3.0
- ipykernel 6.25.0 (required by VS Code)
- jupyter 1.0.0
- notebook 6.5.6
我尝试在 VS Code (1.91.1) 和 jupyter 笔记本中运行 MWE。在 VS Code 中,我的编辑器窗口冻结了:我无法将焦点切换到终端,并且无法在不立即丢失上下文菜单的情况下右键单击任何内容。在 Jupyter Notebook 中,我的窗口没有冻结,并且我没有在界面或控制台中看到任何错误消息,但我也没有看到任何输出。在这两种情况下,我希望看到 Popen 调用的结果(即“1”或“2”)打印在单元格输出中。
通过添加选择,这对我在 JupyterLab 和 altair-5.3.0 中有效,请参阅here,因为您想要交互性:
import altair as alt
import pandas as pd
import subprocess
def on_click(change):
sel = change.new.value[0]
x_sel = df.iloc[sel]["x"]
p = subprocess.Popen(["echo", f"'{x_sel}'"])
df = pd.DataFrame({"x": [1,2], "y": [1,1]})
brush = alt.selection_point("brush")
jchart = alt.JupyterChart(
alt.Chart(df).mark_point(filled=True, size=100, stroke="black").encode(
x=alt.X("x:Q").scale(domain=[0,3]),
y=alt.Y("y:Q").scale(domain=[0,2]),
color=alt.Color("x:Q").legend(None)
).add_params(
brush)
)
jchart.selections.observe(on_click, ["brush"])
jchart
当我像该文档中那样使用
.add_selection()
时,我得到了 AltairDeprecationWarning: 'add_selection' is deprecated. Use 'add_params' instead.
& 所以我改变了它。 YMMV。不知道为什么文档已经过时了。
单击指示会转到 JupyterLab 日志控制台(查找底部功能区上的长指示器亮起),因为当前的 Jupyter 对需要处理的输出有更严格的处理。但您只是询问如何使流程正常运行,因此这证明如果您添加交互性,流程就可以完成。