Plotly散点地图实时更新——标记符号不变
使用Plotly,我想在地图上实时显示一系列符号。
请看下面的情形:
import threading, datetime, dash, time
from dash import dcc, html, dash_table, Patch
from dash.dependencies import Input, Output, State
from plotly.subplots import make_subplots
import plotly.express as px
import plotly.graph_objs as go
class PlotlyApp(threading.Thread):
def __init__(self):
super().__init__(name='PlotlyApp')
self.toggle = False
self.toggle_time = datetime.datetime.now(datetime.timezone.utc)
self.loc_x, self.loc_y = 50, -50
def run(self):
app = dash.Dash(__name__)
self.fig = go.Figure()
self.fig.add_scattermap(lat=[self.loc_x], lon=[self.loc_y])
self.fig.add_scattermap()
self.fig.update_layout(
uirevision=True,
map_style="open-street-map",
map_zoom=18,
map_center_lat = self.loc_x,
map_center_lon=self.loc_y,
margin={"r": 5, "t": 0, "l": 5, "b": 0},
)
app.layout = html.Div([
dcc.Graph(
id='graph',
figure=self.fig,
style={"height": '85vh'},
animate=True,
# config={'responsive':True}
),
dcc.Interval(
id='interval',
interval=1000, # update every 1 second
disabled=False
),
# style={"height": '100vh'}
]),
@app.callback(
Output('graph', 'figure'),
[Input('interval', 'n_intervals')],
# prevent_initial_call=True,
)
def _graph(*args):
now = datetime.datetime.now(datetime.timezone.utc)
changes_x, changes_y = [], []
if now > (self.toggle_time + datetime.timedelta(seconds=10)):
self.toggle = not self.toggle
self.toggle_time = now
print('toggle {}'.format(self.toggle))
if self.toggle:
x1 = self.loc_x - 0.0001
x2 = self.loc_x + 0.0001
y1 = self.loc_y - 0.0001
y2 = self.loc_y + 0.0001
changes_x.extend([
x1,
x2,
x1,
x2
])
changes_y.extend([
y1,
y2,
y2,
y1
])
with self.fig.batch_update():
self.fig.data[1].lat = changes_x
self.fig.data[1].lon = changes_y
self.fig.update_annotations(overwrite=True)
self.fig.update_geos(overwrite=True)
self.fig.update_layout(overwrite=True)
self.fig.update_layout_images(overwrite=True)
self.fig.update_mapboxes(overwrite=True)
self.fig.update_maps(overwrite=True)
self.fig.update_shapes(overwrite=True)
self.fig.update_traces(overwrite=True)
self.dt_update = now
return self.fig
app.run(debug=True, use_reloader=False, dev_tools_ui=True)
if __name__ == "__main__":
pa = PlotlyApp()
pa.run()
while True:
time.sleep(1)
运行该应用显示它在本地主机上运行;在地址处打开后,可以看到地图中央有一个蓝点。
正如脚本所示,每十秒钟会在蓝点周围新增一组点,然后将其移除(同时也会打印出一个“toggle true/false”的信息)。然而,这并没有在视觉上显示出来。
如果在没有周围对象时刷新网页,那么屏幕上只有蓝点可见,永远不会出现其他内容。如果在周围点存在时刷新网页,则会看到蓝点周围出现一组红点……但它们永远不会消失(即使底层数据消失)。
有趣的是,如果将鼠标移到红点上,当存在数据时会有悬停文本显示;而当底层数据被清空时,悬停文本就不再显示。不过红点本身不受影响。
有人知道这是为什么,以及如何实现期望的行为吗?
解决方案
在Plotly社区论坛上找到了一个答案(https://community.plotly.com/t/update-dcc-graph-scattermapbox-on-interval/27744/6):如果我在 dcc.Graph 构造器中移除 animate=True 参数,问题就能解决——周围的点会按预期出现和消失。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。