我有一个与此非常相似的仪表板-
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)
关于python - 更新散点图的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74445610/