python - 更新散点图的最快方法是什么?

标签 python plotly plotly-dash plotly-python

我有一个与此非常相似的仪表板-

import datetime

import dash
from dash import dcc, html
import plotly
from dash.dependencies import Input, Output

# pip install pyorbital
from pyorbital.orbital import Orbital
satellite = Orbital('TERRA')

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div(
    html.Div([
        html.H4('TERRA Satellite Live Feed'),
        html.Div(id='live-update-text'),
        dcc.Graph(id='live-update-graph'),
        dcc.Interval(
            id='interval-component',
            interval=1*1000, # in milliseconds
            n_intervals=0
        )
    ])
)


@app.callback(Output('live-update-text', 'children'),
              Input('interval-component', 'n_intervals'))
def update_metrics(n):
    lon, lat, alt = satellite.get_lonlatalt(datetime.datetime.now())
    style = {'padding': '5px', 'fontSize': '16px'}
    return [
        html.Span('Longitude: {0:.2f}'.format(lon), style=style),
        html.Span('Latitude: {0:.2f}'.format(lat), style=style),
        html.Span('Altitude: {0:0.2f}'.format(alt), style=style)
    ]


# Multiple components can update everytime interval gets fired.
@app.callback(Output('live-update-graph', 'figure'),
              Input('interval-component', 'n_intervals'))
def update_graph_live(n):
    satellite = Orbital('TERRA')
    data = {
        'time': [],
        'Latitude': [],
        'Longitude': [],
        'Altitude': []
    }

    # Collect some data
    for i in range(180):
        time = datetime.datetime.now() - datetime.timedelta(seconds=i*20)
        lon, lat, alt = satellite.get_lonlatalt(
            time
        )
        data['Longitude'].append(lon)
        data['Latitude'].append(lat)
        data['Altitude'].append(alt)
        data['time'].append(time)

    # Create the graph with subplots
    fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2)
    fig['layout']['margin'] = {
        'l': 30, 'r': 10, 'b': 30, 't': 10
    }
    fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}

    fig.append_trace({
        'x': data['time'],
        'y': data['Altitude'],
        'name': 'Altitude',
        'mode': 'lines+markers',
        'type': 'scatter'
    }, 1, 1)
    fig.append_trace({
        'x': data['Longitude'],
        'y': data['Latitude'],
        'text': data['time'],
        'name': 'Longitude vs Latitude',
        'mode': 'lines+markers',
        'type': 'scatter'
    }, 2, 1)

    return fig


if __name__ == '__main__':
    app.run_server(debug=True)

我想更新单个散点图。该散点图大约有两万个数据点。现在这是我的代码:

fig['data'][1]['x'] = dataframe_with_new_data['measure_x']
fig['data'][1]['y'] = dataframe_with_new_data['measure_y']

每次图表更新时,只有几百个新数据点。我担心替换 fig 对象中的整个 x 和 y 条目可能会更慢,但我不确定更快的替代方案是什么样的。

这是具有五百点的示例数据:

import random

x = range(0, 10000, 20)
y = random.sample(range(10, 30000), 500)

最佳答案

您可以使用图形的 extendData 属性将数据添加到现有图形中,而无需每次间隔触发时都从头开始构建图形。正如 documentation 中所写:

extendData (list | dict; optional): Data that should be appended to existing traces. Has the form [updateData, traceIndices, maxPoints], where updateData is an object containing the data to extend, traceIndices (optional) is an array of trace indices that should be extended, and maxPoints (optional) is either an integer defining the maximum number of points allowed or an object with key:value pairs matching updateData

我选择时间间隔 100 毫秒来显示绘制点的速度,没有任何延迟。

import dash
from dash import *
import plotly
import numpy as np 



external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']


app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(
    html.Div([
        dcc.Graph(id='live-update-graph', figure = dict(
                data=[{'x': [0],
                       'y': [0],
                       'name': 'Altitude',
                        'mode': 'lines+markers',
                        'type': 'scatter'
                       }]
            )),
        dcc.Interval(
            id='interval-component',
            interval=100, # in milliseconds
            n_intervals=0
        )
    ])
)


@app.callback(Output('live-update-graph', 'extendData'),
              Input('interval-component', 'n_intervals'),
              [State('live-update-graph', 'figure')])
def update_graph_live(n, existing):
    
    data = {
        'time': [],
        'Altitude': []
    }

    # Collect some data
    
    time = existing['data'][0]['x'][-1] + 1 
    alt = np.random.random()

    return dict(x=[[time]], y=[[alt]])

    

if __name__ == '__main__':
    app.run_server(debug=True)

输出: enter image description here

关于python - 更新散点图的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74445610/

相关文章:

python - Ubuntu Linux : terminal limits the output when I get the full Twitter Streaming API

python - 在 Dash-plotly 中将背景图像添加到 html.div

python-3.x - Pandas:如何使用开始和结束时间戳分析数据?

python - Dash,如何根据点击的按钮进行回调?

python - 将所有内容放在应用程序中心会弄乱 `DatePickerSingle` 和 `RadioItems`

python - 如何将 postman 的不记名 token 读入 Python 代码?

python - 从 Google AppEngine 中的 blobstore 下载 zip 存档

python - 如何使用Selenium获取 parking 价格?

callback - Dash Plotly 在两个页面中共享回调输入

python - Dash dataTable 条件单元格格式不起作用