首页 > 编程问答 >无法在 Altair 中使用 JupyterChart 创建新流程

无法在 Altair 中使用 JupyterChart 创建新流程

时间:2024-08-01 04:15:28浏览次数:9  
标签:python subprocess altair

我有一个 Altair 图表,希望通过以下方式使其具有交互性。当我单击数据点时,我希望通过其 CLI 启动应用程序,并将数据点的属性作为启动命令的参数提供。我的理解是,使用 Altair 5.3.0 中引入的新 JupyterChart 类应该可以实现这一点 - 请参阅示例 此处 但是,按照该示例,当我尝试通过在观察者回调中调用 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”)打印在单元格输出中。


问题在于尝试在 Jupyter 的主线程中运行 subprocess.Popen 。Jupyter 本质上是单线程的,这意味着它一次只能做一件事。当调用 subprocess.Popen 时,它会阻止该线程,直到子进程完成,从而导致 Jupyter 冻结。

为了解决这个问题,需要在一个单独的线程或进程中运行的子进程。这里有几种方法可以做到这一点:

1. 使用 ipywidgets.Output :

这种方法使用 ipywidgets.Output 小部件将子进程的输出捕获到一个单独的输出区域,这样就不会阻塞 Jupyter 的主线程。

import altair as alt
import pandas as pd
import subprocess
from ipywidgets import Output
from IPython.display import display

def on_click(change):
    sel = change.new.value[0]
    x_sel = df.iloc[sel]["x"]

    # 使用 Output 小部件捕获子进程的输出
    out = Output()
    display(out)

    with out:
        p = subprocess.Popen(["echo", f"'{x_sel}'"], stdout=subprocess.PIPE)
        output, _ = p.communicate()
        print(output.decode())

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

2. 使用线程:

这种方法使用 Python 的 threading 模块在一个单独的线程中运行子进程。

import altair as alt
import pandas as pd
import subprocess
import threading

def run_subprocess(x_sel):
    subprocess.Popen(["echo", f"'{x_sel}'"])

def on_click(change):
    sel = change.new.value[0]
    x_sel = df.iloc[sel]["x"]

    # 在一个单独的线程中运行子进程
    thread = threading.Thread(target=run_subprocess, args=(x_sel,))
    thread.start()

# ... rest of the code ...

这两种方法都可以解决 Jupyter 冻结的问题,并允许在单击数据点时运行的应用程序。选择哪种方法取决于的具体需求和偏好。

标签:python,subprocess,altair
From: 78818074

相关文章

  • 如何使用 Selenium (python) 访问另一个影子根中影子根中的元素?
    我有以下代码和HTML结构(我不是这方面的专家)。我正在尝试抓取HTML代码末尾的96.00C元素,其路径是:Xpath://*[@id="_grid"]/set-class2/div2/text-binding//text()完整Xpath:/html/body/main/div/div3/div3/......
  • 在Python中,如何在一段时间内接受输入
    我正在尝试用Python制作一个蛇游戏,但不知道如何制作它,以便蛇在没有玩家输入的情况下继续移动,所以如果有人知道一个简单的方法来做到这一点,我需要在2秒后取消输入将不胜感激代码如下:importrandomimportsysplayerY=(1)playerX=(0)appleY=random.randint(1,10)appl......
  • 在Python中单步执行代码时是否可以引发异常
    当我在IDE(例如PyCharm)中单步执行代码时,我想转储函数的参数(以供以后使用,例如复制它)。计划的场景是在某处设置断点,然后引发异常(这不在我运行的代码中,这就是重点),并捕获它。代码应该如下所示:defexception_cathcher_decorator(func):try:returnfunc(*f_args,**f_k......
  • 解决python自动化操作异常处理的问题
    在python自动化领域,往往要用到pyautogui,pywin32等模块实现自动化操作。然而,这种自动化操作,本身具有一定的局限性,其中最主要的一个问题就是,一旦执行结果不按照脚本预设的来执行,往往会抛出异常,导致程序中断。解决这个问题,主要有这么几种思路:第一,每一次操作后分情况讨论。这种方......
  • Python爬虫入门03:用Urllib假装我们是浏览器
    文章目录引言Urllib库简介Request模块详解Error模块与异常处理Parse模块与URL解析Robotparser模块模拟浏览器请求使用Request方法添加请求头信息代码示例1.设置请求URL和请求头2.定义请求参数并转换为适当的格式3.使用Request方法封装请求4.发送请求并获取响应常用......
  • 请以零基础学Python 之 第二十讲 分组和贪婪匹配
    当我们处理字符串时,有时候需要根据特定的模式来分割或者提取信息。Python提供了强大的正则表达式库re,可以帮助我们实现这些复杂的字符串操作。本篇博客将介绍两个常用的正则表达式技巧:分组和贪婪匹配。分组(Grouping)在正则表达式中,分组是将多个模式单元组合为一个单元,以便......
  • 零基础学python 之 第十九讲 正则表达式
    当你开始学习Python编程时,正则表达式是一项非常强大的工具,用于处理文本数据中的模式匹配和搜索。本篇博客将带你从零开始学习如何在Python中使用正则表达式。1.什么是正则表达式?正则表达式(RegularExpression)是用于描述字符串模式的一种工具,可以用来匹配、查找、替换符合特......
  • python之贪吃蛇
    废话不多说,直接上代码(确保已经安装pygame)importpygameimportrandom#基础设置#屏幕高度SCREEN_HEIGHT=480#屏幕宽度SCREEN_WIDTH=600#小方格大小GRID_SIZE=20#颜色设置WHITE=(255,255,255)BLACK=(0,0,0)GREEN=(0,255,0)#初始化Pyg......
  • Python - Context Managers
    withstatementHereisthesyntaxofthewithstatement:withexpressionasvar:statementsTheexpressionshouldbeacontextmanagerobject,oritshouldproduceacontextmanagerobject.Whenthiswithstatementisexecuted,thefirstthingthat......
  • python装饰器
    一前言环境:win10python3.10二函数中的函数如果定义了一个函数A,现在想在不影响函数A原先功能的情况下,新增加一些额外的功能,怎么办,下面是一个例子如上,本来原先执行test_except那句话只会打印over那句话,但现在执行test_except却会输出一些另外的东西这其中有个巧妙地东西就......