如何基于Plotly在单个Figure对象中实现实时K线图更新?
解决Plotly实时K线图重复打开窗口的问题
你的问题出在每次循环都调用fig.show()——这个方法默认会创建新的渲染实例,导致不断弹出新窗口。要实现单个图表实时更新,推荐使用Plotly的FigureWidget,它支持在同一个窗口内动态更新数据,无需重复调用显示方法。
修改后的完整代码
import pandas as pd import plotly.graph_objects as go from datetime import datetime from time import sleep import random # 初始化数据框 ohlc_data = pd.DataFrame(columns=["timestamp", "open", "high", "low", "close", "volume"]) # 用FigureWidget替代普通Figure,支持实时更新 fig = go.FigureWidget(data=[go.Candlestick(x=[], open=[], high=[], low=[], close=[])]) fig.update_layout(title=f'Live Candlestick Chart', xaxis_title='Time', yaxis_title='Price') # 只需要显示一次图表 fig.show() def update_live_chart(fig, df): # 直接更新trace的数据,FigureWidget会自动同步到已打开的图表 fig.data[0].x = df['timestamp'] fig.data[0].open = df['open'] fig.data[0].high = df['high'] fig.data[0].low = df['low'] fig.data[0].close = df['close'] while True: sleep(1) # 生成新数据 new_data = pd.DataFrame([{ "timestamp": datetime.now(), # 用datetime对象,图表时间显示更友好 "open": random.randint(100, 110), "high": random.randint(100, 110), "low": random.randint(100, 110), "close": random.randint(100, 110), "volume": random.randint(100, 110) }]) # 更新数据并保留最近100条 ohlc_data = pd.concat([ohlc_data, new_data], ignore_index=True) ohlc_data = ohlc_data.tail(100) # 更新图表 update_live_chart(fig, ohlc_data)
关键改动说明
- 替换Figure为FigureWidget:这是实现实时更新的核心,FigureWidget是交互式组件,修改其数据会自动同步到已打开的图表窗口。
- 只调用一次fig.show():初始化后显示一次图表即可,后续更新无需重复调用。
- 直接修改trace数据:在更新函数里直接赋值给
fig.data[0]的各个字段,替代原有的update_traces(两种方式都可用,直接赋值更直观)。 - 优化时间戳显示:把
timestamp()改成datetime.now(),图表X轴会显示可读的时间格式,而非纯数字时间戳。
注意事项
- Jupyter环境中默认支持FigureWidget的交互式更新,无需额外配置。
- 桌面环境运行需确保安装Plotly的依赖后端(如
ipywidgets),保证组件正常渲染。
内容的提问来源于stack exchange,提问作者shashashamti2008
相关产品推荐
相关产品推荐

