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

PyQt中如何离线使用Plotly无需重绘整张图即可更新数据?

优化方案

核心思路

原有实现每次触发更新都会重新生成完整HTML并让QWebEngineView全量重加载,相当于重新渲染整个页面,自然流畅度差。我们可以利用Plotly原生的JS更新接口,仅更新折线数据,无需重绘整个图表,保留原有坐标轴等全部配置。

关键修改点

  • 初始化阶段仅生成一次HTML结构,同时将Plotly图表实例绑定到JS全局变量方便后续调用
  • 数据更新阶段通过QWebEngineView.runJavaScript()调用Plotly的restyle接口,仅替换目标折线的x/y数据,不会触发全页面重绘

完整优化代码

from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import *
import plotly.graph_objects as go
import plotly
import numpy as np
import json


class Window(QWidget):

    def __init__(self):
        super(Window, self).__init__()
        grid_layout = QGridLayout()
        self.pb = QPushButton('plot')

        # 初始化示例数据
        x = np.arange(0, 2*np.pi, 0.001)
        y = np.sin(x)
        fig = go.Figure(go.Scatter(x=x, y=y))

        # 生成HTML时保留Plotly实例引用到全局变量
        plot_div = plotly.offline.plot(fig, output_type='div', include_plotlyjs='cdn')
        # 加一段JS把生成的图表实例存到window下,方便后续调用
        html = f"""
        <html>
        <body>
        {plot_div}
        <script>
        // 把页面里的第一个Plotly实例存为全局变量
        window.plotlyFig = document.getElementsByClassName('plotly-graph-div')[0];
        </script>
        </body>
        </html>
        """
        self.plot_widget = QWebEngineView()
        self.plot_widget.setHtml(html)

        grid_layout.addWidget(self.plot_widget, 0, 0)
        grid_layout.addWidget(self.pb, 1, 0)
        self.setLayout(grid_layout)
        self.pb.clicked.connect(self.newplot)

    def newplot(self):
        # 生成新数据
        x = np.arange(0, 2 * np.pi, 0.001)
        y = np.sin(x+np.random.uniform(low=0, high=2*np.pi))
        # 把数据序列化为JSON格式传给JS
        x_json = json.dumps(x.tolist())
        y_json = json.dumps(y.tolist())
        # 调用Plotly.restyle仅更新第一条折线的x和y数据
        self.plot_widget.page().runJavaScript(f"""
        Plotly.restyle(window.plotlyFig, {{
            x: [{x_json}],
            y: [{y_json}]
        }}, [0]);
        """)


if __name__ == '__main__':
    app = QApplication([])
    window = Window()
    window.show()
    app.exec_()

效果说明

该方案仅更新数据部分,不会重新加载整个页面,更新延迟大幅降低,原有坐标轴的缩放、自定义配置等都会完整保留,不会被重置。

内容的提问来源于stack exchange,提问作者Victor Y.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:24:00