我是 plotly
新手,希望可视化正在运行的事件中的数据。假设我有一个包含以下列的数据框:
df = pd.DataFrame(
{
"time": time,
"latitude": latitude,
"longitude": longitude,
"altitude": altitude,
"heartrate": heartrate,
}
)
我想要两个图,一个是绘制纬度与经度的 map ,另一个是绘制时间与心率(或海拔)的图。 但我希望这两个 plotly 能够联系起来。因此,如果我在第二个图中选择 y 范围,我只想在 map 上看到那些纬度-经度对,其中它们各自的时间值位于我在第二个图中选择的范围内。同样,如果我在 map 上选择点,我想查找该点选择中的最小和最大时间值,并希望仅在第二个图中绘制这些点。
我不知道如何链接这两个图,所以非常感谢您的帮助! 源码如下:
import dash
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objs as go
app = dash.Dash()
server = app.server
np.random.seed(0)
# Random dummy data
n = 100
time = np.linspace(0, 1, n)
latitude = 50 + 0.001 * np.cumsum(np.random.randn(n))
longitude = 2 + 0.001 * np.cumsum(np.random.randn(n))
altitude = (time - 0.5) ** 2
heartrate = 100 + np.cumsum(np.random.randn(n))
df = pd.DataFrame(
{
"time": time,
"latitude": latitude,
"longitude": longitude,
"altitude": altitude,
"heartrate": heartrate,
}
)
fig = px.line_mapbox(df, lat="latitude", lon="longitude", zoom=12, height=800)
fig.update_layout(mapbox_style="stamen-terrain")
app.layout = html.Div(
[
html.Div(
[
dcc.Graph(id="mymap", figure=fig),
]
),
html.Div(
[
dcc.Graph(id="time-series"),
dcc.Dropdown(
id="column",
options=[
{"label": i, "value": i} for i in ["altitude", "heartrate"]
],
value="altitude",
),
]
),
]
)
def lineplot(x, y, title="", axis_type="Linear"):
return {
"data": [go.Scatter(x=x, y=y, mode="lines")],
}
@app.callback(
dash.dependencies.Output("time-series", "figure"),
[
dash.dependencies.Input("column", "value"),
],
)
def update_timeseries(column):
x = df["time"]
y = df[column]
return lineplot(x, y)
app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"})
if __name__ == "__main__":
app.run_server(debug=True)
最佳答案
这是一个选项,我将行 map 框更改为散点图框,以便您可以进行框选择
并查看 map 中所选数据的代码和折线图中的过滤器的代码
import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output, State
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objs as go
app = dash.Dash()
server = app.server
np.random.seed(0)
# Random dummy data
n = 100
time = np.linspace(0, 1, n)
latitude = 50 + 0.001 * np.cumsum(np.random.randn(n))
longitude = 2 + 0.001 * np.cumsum(np.random.randn(n))
altitude = (time - 0.5) ** 2
heartrate = 100 + np.cumsum(np.random.randn(n))
df = pd.DataFrame(
{
"time": time,
"latitude": latitude,
"longitude": longitude,
"altitude": altitude,
"heartrate": heartrate,
}
)
fig = go.Figure(go.Scattermapbox(
mode = "markers+lines",
lon = df.longitude,
lat = df.latitude,
marker = {'size': 10}))
fig.update_layout(
mapbox={
'style': "stamen-terrain",
'center' : dict(
lat=50,
lon=2
),
'zoom': 12})
app.layout = html.Div(
[
html.Div(
[
dcc.Graph(id="mymap", figure=fig),
]
),
html.Div(
[
dcc.Graph(id="time-series"),
dcc.Dropdown(
id="column",
options=[
{"label": i, "value": i} for i in ["altitude", "heartrate"]
],
value="altitude",
),
]
),
]
)
def lineplot(x, y, title="", axis_type="Linear"):
return {
"data": [go.Scatter(x=x, y=y, mode="lines")],
}
@app.callback(
Output("time-series", "figure"),
[
Input("column", "value"),
Input("mymap", "selectedData")
],
)
def update_timeseries(column, selectedData):
# add filter data by selectData points
temp = df
if selectedData is not None:
sel_data = pd.DataFrame(selectedData['points'])
temp = df.loc[(df.latitude.isin(sel_data.lat)) & (df.longitude.isin(sel_data.lon))]
x = temp["time"]
y = temp[column]
return lineplot(x, y)
app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"})
if __name__ == "__main__":
app.run_server(debug=True)
关于python - `line_mapbox` 和第二个图之间的交叉过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68988634/