You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Taipy GUI实现无按钮触发的图表每2秒实时数据更新

在Taipy GUI中实现优雅的实时数据更新(每2秒自动刷新)

我需要在Taipy GUI中展示实时接收的数据,要求图表每2秒自动更新,无需按钮等外部触发事件。尝试通过线程修改图表数据,但图表及地图会持续刷新,显示效果不够优雅,相关代码如下:

from taipy.gui import Gui, notify
import threading
import time

text = "Original text"

list_to_display = [100/x for x in range(1, 100)]
list_to_display_1 = list_to_display
is_first_time = True


data = {"x_col":[0,1,2], "y_col1":[4,1,2]}

# Flight start and end locations
data_map = {
    # Hartsfield-Jackson Atlanta International Airport 
    # to
    # Aéroport de Paris-Charles de Gaulle
    "lat": [33.64, 49.01],
    "lon": [-84.44, 2.55],
}

layout_map = {
    # Chart title
    "title": "ATL to CDG",
    # Hide legend
    "showlegend": False,
    # Focus on relevant area
    "geo": {
        "resolution": 50,
        "showland": True,
        "showocean": True,
        "landcolor": "4a4",
        "oceancolor": "77d",
        "lataxis": {
            "range": [20, 60]
        },
        "lonaxis": {
            "range": [-100, 20]
        }
    }
}

# Flight displayed as a thick, red plot
line_map = {
    "width": 5,
    "color": "red"
}


page = """
# Getting started with Taipy GUI

My text: <|{text}|>

<|{text}|input|>

<|Run local|button|on_action=on_button_action|>

<|{data}|chart|x=x_col|y[1]=y_col1|y[2]=y_col1|>

<|{data_map}|chart|type=scattergeo|mode=lines|lat=lat|lon=lon|line={line_map}|layout={layout_map}|>

"""

def on_button_action(state):
    global is_first_time
    notify(state, 'info', f'The text is: {state.text}')
    state.text = "Button Pressed"
    if state.is_first_time == True:
        threading.Thread(target=update_list(state), daemon=True).start()
        state.is_first_time = False

def on_change(state, var_name, var_value):
    if var_name == "text" and var_value == "Reset":
        state.text = ""
        return

def update_list(state):
    i = 0
    while True:
        i += 1
        list_to_display.append(0)
        list_to_display.pop(0)
        state.list_to_display_1 = list_to_display
        data_1 = data
        data_1["x_col"].append(7)
        data_1["y_col1"].append(2)
        state.data = data_1
        data_map_1 = data_map
        data_map_1["lat"][1] += 1
        state.data_map = data_map_1
        time.sleep(2)

Gui(page=page).run(dark_mode=False,port=5002, host='0.0.0.0')

问题分析

  • 线程启动错误:threading.Thread(target=update_list(state))会直接执行update_list函数,而非将其作为线程目标,正确写法应传递函数引用和参数。
  • 全量刷新触发:每次更新时重新赋值整个字典(如state.data = data_1),Taipy会检测到对象引用变化,触发组件全量重新渲染,导致刷新不优雅。
  • 依赖按钮触发:当前逻辑需要点击按钮才启动线程,不符合“无需外部触发”的需求。

修改方案

  1. 使用on_init回调在GUI启动时自动启动更新线程
  2. 直接修改state内的对象元素,而非重新赋值整个字典,减少不必要的渲染
  3. 修正线程启动方式,正确传递state参数
  4. 可选:限制数据序列长度,避免数据无限累积

修改后的完整代码

from taipy.gui import Gui, notify
import threading
import time

text = "Original text"

list_to_display = [100/x for x in range(1, 100)]
list_to_display_1 = list_to_display

# 初始化图表数据
data = {"x_col":[0,1,2], "y_col1":[4,1,2]}

# 初始化地图数据
data_map = {
    "lat": [33.64, 49.01],
    "lon": [-84.44, 2.55],
}

layout_map = {
    "title": "ATL to CDG",
    "showlegend": False,
    "geo": {
        "resolution": 50,
        "showland": True,
        "showocean": True,
        "landcolor": "4a4",
        "oceancolor": "77d",
        "lataxis": {"range": [20, 60]},
        "lonaxis": {"range": [-100, 20]}
    }
}

line_map = {
    "width": 5,
    "color": "red"
}

page = """
# Getting started with Taipy GUI

My text: <|{text}|>

<|{text}|input|>

<|{data}|chart|x=x_col|y[1]=y_col1|y[2]=y_col1|>

<|{data_map}|chart|type=scattergeo|mode=lines|lat=lat|lon=lon|line={line_map}|layout={layout_map}|>
"""

def on_init(state):
    # GUI初始化后启动更新线程
    threading.Thread(target=update_list, args=(state,), daemon=True).start()

def on_change(state, var_name, var_value):
    if var_name == "text" and var_value == "Reset":
        state.text = ""
        return

def update_list(state):
    while True:
        # 更新列表数据
        list_to_display.append(0)
        list_to_display.pop(0)
        state.list_to_display_1 = list_to_display.copy()  # 使用copy避免引用同一对象
        
        # 更新图表数据:直接修改state内的字典元素,不重新赋值整个字典
        state.data["x_col"].append(state.data["x_col"][-1] + 1)
        state.data["y_col1"].append((state.data["y_col1"][-1] + 1) % 10)
        # 可选:限制x_col长度,保持图表显示最新N个数据
        if len(state.data["x_col"]) > 20:
            state.data["x_col"].pop(0)
            state.data["y_col1"].pop(0)
        
        # 更新地图数据:直接修改state内的列表元素
        state.data_map["lat"][1] += 0.5
        if state.data_map["lat"][1] > 60:
            state.data_map["lat"][1] = 49.01  # 重置位置
        
        time.sleep(2)

Gui(page=page).run(dark_mode=False, port=5002, host='0.0.0.0')

关键改动说明

  • 自动启动线程:通过on_init回调,GUI启动后自动开始更新,无需按钮触发。
  • 增量更新数据:直接修改state.data和state.data_map内部的元素,而非重新赋值整个字典,Taipy会检测到内部数据变化,执行局部刷新,提升显示优雅度。
  • 修正线程启动:threading.Thread(target=update_list, args=(state,))正确传递函数引用和参数,避免直接执行函数。
  • 数据长度控制:添加数据长度限制,防止数据无限增长导致图表性能下降。

内容的提问来源于stack exchange,提问作者i h

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:00:39