Plotly mapbox:获取当前视图/缩放级别的几何图形
Plotly mapbox : Get the geometry of current view / zoom level
我正在 Flask / Dash 应用程序中使用 plotly 渲染 scattermapbox
。我设置了默认的 zoom
级别和 lat
,long
坐标。当用户通过 plotly 界面平移地图并更改缩放级别时,我想用点和数据层更新地图。
这里有一些代码供参考:
import pandas as pd
import geopandas as gpd
# import mapbox
import requests
import plotly.graph_objects as go
# Update with host url
df_geo = gpd.GeoDataFrame.from_features(
requests.get(
"https://eric.clst.org/assets/wiki/uploads/Stuff/gz_2010_us_050_00_20m.json"
).json()
)
import plotly.graph_objects as go
fig = go.Figure(
go.Choroplethmapbox(
geojson=df_geo.set_index("GEO_ID")["geometry"].__geo_interface__,
locations=df_geo["GEO_ID"],
z=df_geo["CENSUSAREA"],
autocolorscale=False,
colorscale="Viridis",
zmin=df_geo["CENSUSAREA"].min(),
zmax=df_geo["CENSUSAREA"].quantile(0.95),
marker_line_width=0,
colorbar={"orientation": "h", "x": 0.5, "yanchor": "middle", "y": 0.1},
)
)
fig.update_layout(
mapbox_style="carto-positron",
# mapbox_accesstoken=token,
mapbox_zoom=3,
mapbox_center={"lat": 37.0902, "lon": -95.7129},
margin={"r": 0, "t": 0, "l": 0, "b": 0},
)
fig.show()
我的问题是,如何获取当前地图视图的geometries / bbox
或lat,longs coords
?
文档链接以供参考:
mapbox 上的 - relayoutData return center 和 coordinates
- 已通过使用客户端回调将此插入到跟踪中进行了演示。这是可行的,但是为了提高效率,我真的只想更新图形而不是 re-render 它。
import pandas as pd
import geopandas as gpd
import requests
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
import dash
from dash.dependencies import Input, Output, State
import json
# Update with host url
df_geo = gpd.GeoDataFrame.from_features(
requests.get(
"https://eric.clst.org/assets/wiki/uploads/Stuff/gz_2010_us_050_00_20m.json"
).json()
)
fig = go.Figure(
[
go.Choroplethmapbox(
geojson=df_geo.set_index("GEO_ID")["geometry"].__geo_interface__,
locations=df_geo["GEO_ID"],
z=df_geo["CENSUSAREA"],
autocolorscale=False,
colorscale="Viridis",
zmin=df_geo["CENSUSAREA"].min(),
zmax=df_geo["CENSUSAREA"].quantile(0.95),
marker_line_width=0,
name="choropleth"
# colorbar={"orientation": "h", "x": 0.5, "yanchor": "middle", "y": 0.1},
),
go.Scattermapbox(
name="scatter", marker={"size": 30, "color": "red", "opacity": 1}
),
]
)
fig.update_layout(
mapbox_style="carto-positron",
# mapbox_accesstoken=token,
mapbox_zoom=3,
mapbox_center={"lat": 37.0902, "lon": -95.7129},
margin={"r": 0, "t": 0, "l": 0, "b": 0},
datarevision=0,
height=300,
width=600,
autosize=False,
)
# Build App
app = JupyterDash(__name__)
app.layout = dash.html.Div(
[
dash.dcc.Checklist(
options=[{"label":"refesh", "value":"yes"}],
id="refresh",
),
dash.dcc.Graph(id="mapbox_fig", figure=fig),
dash.html.Div(
id="debug_container",
),
dash.dcc.Store(
id="points-store",
data={
"lat": [],
"lon": [],
},
),
]
)
@app.callback(
Output("points-store", "data"),
Output("debug_container", "children"),
Input("mapbox_fig", "relayoutData"),
Input("refresh","value")
)
def mapbox_cb(mapbox_cfg, refresh):
try:
refresh = refresh[0]=="yes"
except Exception:
refresh = False
if mapbox_cfg and "mapbox.zoom" in mapbox_cfg.keys() and refresh:
bbox = np.array(mapbox_cfg["mapbox._derived"]["coordinates"])
# bbox = bbox * .8
data = {
"lon": bbox[:, 0].tolist() + [mapbox_cfg["mapbox.center"]["lon"]],
"lat": bbox[:, 1].tolist() + [mapbox_cfg["mapbox.center"]["lat"]],
}
return data, [
dash.html.Pre(json.dumps(mapbox_cfg, indent=2)),
dash.html.Pre(json.dumps(data, indent=2)),
]
else:
raise dash.exceptions.PreventUpdate
app.clientside_callback(
"""
function(data, fig) {
fig.data[1]['lat'] = data['lat'];
fig.data[1]['lon'] = data['lon'];
fig.layout.datarevision = fig.layout.datarevision + 1;
/* return fig; */
return JSON.parse(JSON.stringify(fig));
}
""",
Output("mapbox_fig", "figure"),
Input("points-store", "data"),
State("mapbox_fig", "figure"),
)
app.run_server(mode="inline")
我正在 Flask / Dash 应用程序中使用 plotly 渲染 scattermapbox
。我设置了默认的 zoom
级别和 lat
,long
坐标。当用户通过 plotly 界面平移地图并更改缩放级别时,我想用点和数据层更新地图。
这里有一些代码供参考:
import pandas as pd
import geopandas as gpd
# import mapbox
import requests
import plotly.graph_objects as go
# Update with host url
df_geo = gpd.GeoDataFrame.from_features(
requests.get(
"https://eric.clst.org/assets/wiki/uploads/Stuff/gz_2010_us_050_00_20m.json"
).json()
)
import plotly.graph_objects as go
fig = go.Figure(
go.Choroplethmapbox(
geojson=df_geo.set_index("GEO_ID")["geometry"].__geo_interface__,
locations=df_geo["GEO_ID"],
z=df_geo["CENSUSAREA"],
autocolorscale=False,
colorscale="Viridis",
zmin=df_geo["CENSUSAREA"].min(),
zmax=df_geo["CENSUSAREA"].quantile(0.95),
marker_line_width=0,
colorbar={"orientation": "h", "x": 0.5, "yanchor": "middle", "y": 0.1},
)
)
fig.update_layout(
mapbox_style="carto-positron",
# mapbox_accesstoken=token,
mapbox_zoom=3,
mapbox_center={"lat": 37.0902, "lon": -95.7129},
margin={"r": 0, "t": 0, "l": 0, "b": 0},
)
fig.show()
我的问题是,如何获取当前地图视图的geometries / bbox
或lat,longs coords
?
文档链接以供参考:
-
mapbox 上的
- relayoutData return center 和 coordinates
- 已通过使用客户端回调将此插入到跟踪中进行了演示。这是可行的,但是为了提高效率,我真的只想更新图形而不是 re-render 它。
import pandas as pd
import geopandas as gpd
import requests
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
import dash
from dash.dependencies import Input, Output, State
import json
# Update with host url
df_geo = gpd.GeoDataFrame.from_features(
requests.get(
"https://eric.clst.org/assets/wiki/uploads/Stuff/gz_2010_us_050_00_20m.json"
).json()
)
fig = go.Figure(
[
go.Choroplethmapbox(
geojson=df_geo.set_index("GEO_ID")["geometry"].__geo_interface__,
locations=df_geo["GEO_ID"],
z=df_geo["CENSUSAREA"],
autocolorscale=False,
colorscale="Viridis",
zmin=df_geo["CENSUSAREA"].min(),
zmax=df_geo["CENSUSAREA"].quantile(0.95),
marker_line_width=0,
name="choropleth"
# colorbar={"orientation": "h", "x": 0.5, "yanchor": "middle", "y": 0.1},
),
go.Scattermapbox(
name="scatter", marker={"size": 30, "color": "red", "opacity": 1}
),
]
)
fig.update_layout(
mapbox_style="carto-positron",
# mapbox_accesstoken=token,
mapbox_zoom=3,
mapbox_center={"lat": 37.0902, "lon": -95.7129},
margin={"r": 0, "t": 0, "l": 0, "b": 0},
datarevision=0,
height=300,
width=600,
autosize=False,
)
# Build App
app = JupyterDash(__name__)
app.layout = dash.html.Div(
[
dash.dcc.Checklist(
options=[{"label":"refesh", "value":"yes"}],
id="refresh",
),
dash.dcc.Graph(id="mapbox_fig", figure=fig),
dash.html.Div(
id="debug_container",
),
dash.dcc.Store(
id="points-store",
data={
"lat": [],
"lon": [],
},
),
]
)
@app.callback(
Output("points-store", "data"),
Output("debug_container", "children"),
Input("mapbox_fig", "relayoutData"),
Input("refresh","value")
)
def mapbox_cb(mapbox_cfg, refresh):
try:
refresh = refresh[0]=="yes"
except Exception:
refresh = False
if mapbox_cfg and "mapbox.zoom" in mapbox_cfg.keys() and refresh:
bbox = np.array(mapbox_cfg["mapbox._derived"]["coordinates"])
# bbox = bbox * .8
data = {
"lon": bbox[:, 0].tolist() + [mapbox_cfg["mapbox.center"]["lon"]],
"lat": bbox[:, 1].tolist() + [mapbox_cfg["mapbox.center"]["lat"]],
}
return data, [
dash.html.Pre(json.dumps(mapbox_cfg, indent=2)),
dash.html.Pre(json.dumps(data, indent=2)),
]
else:
raise dash.exceptions.PreventUpdate
app.clientside_callback(
"""
function(data, fig) {
fig.data[1]['lat'] = data['lat'];
fig.data[1]['lon'] = data['lon'];
fig.layout.datarevision = fig.layout.datarevision + 1;
/* return fig; */
return JSON.parse(JSON.stringify(fig));
}
""",
Output("mapbox_fig", "figure"),
Input("points-store", "data"),
State("mapbox_fig", "figure"),
)
app.run_server(mode="inline")