如何基于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会检测到对象引用变化,触发组件全量重新渲染,导致刷新不优雅。 - 依赖按钮触发:当前逻辑需要点击按钮才启动线程,不符合“无需外部触发”的需求。
修改方案
- 使用
on_init回调在GUI启动时自动启动更新线程 - 直接修改
state内的对象元素,而非重新赋值整个字典,减少不必要的渲染 - 修正线程启动方式,正确传递
state参数 - 可选:限制数据序列长度,避免数据无限累积
修改后的完整代码
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
相关产品推荐
相关产品推荐

