Plotly:如何用新数据更新/重绘绘图表达图形?

问题描述 投票:0回答:3

在调试或计算量大的循环期间,我想看看我的数据处理如何演变(例如在线图或图像中)。

在 matplotlib 中,代码可以使用

plt.cla()
然后使用
plt.draw()
plt.pause(0.001)
重绘/更新图形,以便我可以实时或在调试时跟踪计算进度。我如何在情节表达(或情节)中做到这一点?

python plot plotly redraw plotly-express
3个回答
14
投票

所以我想我基本上已经弄清楚了。诀窍是不要使用

go.Figure()
来创建图形,而是使用
go.FigureWidget()
,这在视觉上是相同的东西,但在幕后却不是。

文档

youtube视频演示

这些FigureWidgets 完全可以随着新数据的到来而更新。它们保持动态,以后的调用可以修改它们。

FigureWidget 可以由Figure 制作:

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

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

这很实用,因为它使得可以使用简化的plotlyexpress接口来创建一个Figure,然后使用它来构造一个FigureWidget。不幸的是,plotlyexpress似乎没有自己的简化FigureWidget模块。所以需要使用更复杂的

go.FigureWidget


4
投票

我不确定情节是否存在相同的功能。但您至少可以构建一个图形,扩展数据源,然后只替换图形的数据,而不接触任何其他图形元素,如下所示:

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()

单元格 2 的代码

# 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()

运行第一个单元格将汇集一些数据并构建如下图:

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


0
投票

另一种方法是使用

extendData
但仅保留您扩展的数据。这是一种使用常见 Plotly 方法的简单方法,但我不确定速度和鲁棒性。

如果您有 2D 散点图,您可以执行以下操作:

@app.callback(
    Output("graph", "extendData"), 
    Input("foo", "foo_bar"))
def update_graph(figure):
    new_x_coords = # Your new x coordinates
    new_y_coords = # Your new y coordinates
    return dict(x=[new_x_coords], y=[new_y_coords), [0], len(new_x_coords)

此处

[0]
表示图中的第一条迹线,但您可以将其更改为任何其他迹线。您可以使用
dcc.Interval
触发此回调来制作动画。另一种选择是输入数字以更新绘图上的各个点。一个例子可能是:

@app.callback(
    Output("graph", "extendData"), 
    Input("interval", "n_intervals"),
    Input("graph", "figure"))
def update_graph(n_intervals, figure):
    old_x_coords = figure['data'][0]['x']
    new_x_coords = [n_intervals] + old_x_coords[1:]
    return dict(x = [new_x_coords]), [0], len(new_x_coords)
© www.soinside.com 2019 - 2024. All rights reserved.