Plotly:如何使用新数据更新/重绘Plotly Express图表?

11

在调试或计算密集的循环中,我希望能够看到我的数据处理如何演变(例如在一条折线图或图像中)。

在 matplotlib 中,可以使用 plt.cla() 然后使用 plt.draw()plt.pause(0.001) 来重新绘制 / 更新图形,这样我就可以实时跟踪计算进度或进行调试。在 plotly express(或 plotly)中如何做到呢?


我会研究一下plotly动画 - Derek O
该页面上的所有示例都使用预先计算好的数据,只需要将其显示为动画即可。可能可以通过使其调用生成器或迭代器来检索下一个数据点,在figure字典的frames=[..]部分内外包计算。不确定。 - Jim
2个回答

13

我想我基本上弄清楚了。诀窍在于不使用go.Figure()创建图形,而是使用go.FigureWidget(),它在视觉上看起来相同,但在幕后并非如此。

文档

Youtube视频演示

这些 FigureWidgets 正好可以被更新,以便随着新数据的出现进行更新。 它们保持动态,并且稍后的调用可以修改它们。

可以从一个 Figure 创建一个 FigureWidget:

figure = go.Figure(data=data, layout=layout)

f2 = go.FigureWidget(figure)
f2                                          #display the figure

这很实用,因为它使得使用简化的plotly express接口创建一个Figure成为可能,并将其用于构建FigureWidget。不幸的是,plotly express似乎没有自己的简化FigureWidget模块。因此,需要使用更复杂的go.FigureWidget。

为了在Google Colab上使用这个,我还需要额外的权限,具体形式为: from google.colab import output; output.enable_custom_widget_manager() - Neil Traft

4
我不确定 Plotly 是否存在相同的功能。但是,您至少可以构建一个图形,扩展数据源,然后只需替换图形的数据而不触及任何其他图形元素,就像这样:
for i, col in enumerate(fig.data):
    fig.data[i]['y'] = df[df.columns[i]]
    fig.data[i]['x'] = df.index

无论使用 plotly.express 还是 go.Figure ,都不应该影响您的图形,因为这两种方法都会产生可以通过上面的代码片段进行编辑的图形结构。您可以通过在JupyterLab中设置以下两个片段来测试此功能。

单元格1的代码

import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

# code and plot setup
# settings
pd.options.plotting.backend = "plotly"

# sample dataframe of a wide format
np.random.seed(5); cols = list('abc')
X = np.random.randn(50,len(cols))  
df=pd.DataFrame(X, columns=cols)
df.iloc[0]=0;df=df.cumsum()

# plotly figure
fig = df.plot(template = 'plotly_dark')
fig.show()

第二个单元格的代码

# create or retrieve new data
Y = np.random.randn(1,len(cols))

# organize new data in a df
df2 = pd.DataFrame(Y, columns = cols)

# add last row to df to new values
# this step can be skipped if your real world
# data is not a cumulative process like
# in this example
df2.iloc[-1] = df2.iloc[-1] + df.iloc[-1]

# append new data to existing df
df = df.append(df2, ignore_index=True)#.reset_index()

# replace old data in fig with new data
for i, col in enumerate(fig.data):
    fig.data[i]['y'] = df[df.columns[i]]
    fig.data[i]['x'] = df.index

fig.show()

运行第一个单元格将会整理一些数据并构建出如下图所示的图形:

enter image description here

运行第二个单元格将生成一个只有一行的新数据框,将其附加到原始数据框中,替换现有图表中的数据,并再次显示图表。您可以运行第二个单元格多次,以使用扩展数据集重新绘制图表。经过50次运行,您的图表将如下所示:

enter image description here


1
仅供开发使用。可以是独立的.py程序,也可以使用Jupyter笔记本,但如果它弹出并在浏览器中显示,那也没关系。事实上,我甚至更喜欢这样。 - Jim
我现在正在Jupyter笔记本上运行它。但是当我执行该单元格时,什么也没有发生。显示器去哪了?对不起我的无知,但我平常编程并不使用这种技术。甚至似乎无法停止该单元格的执行。它只是一直运行并且什么也不显示。 - Jim
@Jim 嗯...好的。那么,我提供的上面链接中的确切片段不起作用吗? - vestland
@Jim,我正在为一个旧问题准备新的答案,应该会涵盖所有这些内容。我还需要10-15分钟就可以完成,如果你感兴趣,我很乐意在这里提供链接。 - vestland
太棒了!谢谢你! - Jim
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接