plotly中的插入贴图(python)

fv2wmkja  于 2021-09-08  发布在  Java
关注(0)|答案(1)|浏览(404)

我目前正在尝试使用python中的plotly express和mapbox绘制一些Map。
我需要有一个国家的大Map,旁边是一个带“缩放”到特定地区的插图Map(见附图作为示例)插图Map示例。
我设法绘制了更大的Map(即整个国家),但找不到正确的方法来创建插图Map。
我试图制作2个子图(1行,2列),但没有按预期工作。他还试图同时绘制两个图形(一个较大的是整个国家,另一个较小的是插图Map),但这两个图形“碰撞”(插图Map位于另一个的顶部)。
对此有什么想法或可能的转变吗?
非常感谢。

izj3ouym

izj3ouym1#

已使用dash启用从主choropeth的回调以更新InsettChoroPeth(我构建dash html的方式意味着它是开始…)
为了将所有这些结合起来,我使用了来自英国政府来源的一些地理测绘数据
我们刚刚在回调中修改了合唱团的中心。还可以修改缩放和/或范围

获取一些地理数据

import requests
import geopandas as gpd
import pandas as pd

# https://ons-inspire.esriuk.com/arcgis/rest/services/Administrative_Boundaries/Local_Authority_Districts_December_2017_Boundaries/MapServer/3/query?where=1%3D1&outFields=*&outSR=4326&f=json

# res = requests.get("https://opendata.arcgis.com/datasets/ae90afc385c04d869bc8cf8890bd1bcd_3.geojson")

res = requests.get(
    "https://opendata.arcgis.com/datasets/69dc11c7386943b4ad8893c45648b1e1_0.geojson"
)

# use 2019 so Buckinghamshire is included

rescounties = requests.get(
    "https://opendata.arcgis.com/datasets/37363d379f4f40fa8c3f0d28eedfdd37_0.geojson"
)
gdf = pd.concat(
    [
        gpd.GeoDataFrame.from_features(res.json()["features"], crs="CRS84")
        .pipe(lambda d: d.rename(columns={c: c.lower() for c in d.columns}).drop(columns="lad20nmw"))
        .rename(columns={"lad20cd": "areaCode", "lad20nm": "areaName"}),
        gpd.GeoDataFrame.from_features(rescounties.json()["features"], crs="CRS84")
        .pipe(lambda d: d.rename(columns={c: c.lower() for c in d.columns}))
        .rename(columns={"cty19cd": "areaCode","cty20cd": "areaCode","cty19nm": "areaName","st_areashape": "shape__area",
                         "st_lengthshape": "shape__length",}),
    ]
).set_index("areaCode").assign(country=lambda d: d.index.str[0])

建立基数

import plotly.express as px
fig = px.choropleth_mapbox(
    gdf,
    geojson=gdf.geometry,
    locations=gdf.index,
    hover_name="areaName",
    color="country",
    color_discrete_sequence=["green", "yellow", "orange", "red", "magenta"],
    center={"lat": (gdf.total_bounds[1] + gdf.total_bounds[3])/2, "lon": (gdf.total_bounds[0] + gdf.total_bounds[2])/2},
    mapbox_style="carto-positron",
    zoom=5,
).update_layout(margin={"l":0,"r":0,"b":0,"t":0})

dash应用程序

import json
import numpy as np
import plotly.graph_objects as go
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc

import dash_table
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash

ifig = go.Figure(fig.data).update_layout(fig.layout).update_layout(showlegend=False)

# Build App

app = JupyterDash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div(
    [
        dbc.Row(
            [
                dbc.Col(
                    dcc.Graph(id="map", figure=fig, style={"height": "90vh"}),
                    width=9,
                ),
                dbc.Col(
                    dcc.Graph(id="insetmap", style={"height": "25vh"}),
                    width=3,
                ),
            ]
        ),
    ],
    style={"font-family": "Arial", "font-size": "0.9em"},
)

@app.callback(
    Output("insetmap", "figure"),
    Input("map", "selectedData"),
)
def mapSelect(selectData):
    global ifig
    if selectData and "range" in selectData.keys():
        r = selectData["range"]["mapbox"]
        ifig = ifig.update_layout(
            mapbox={
                "center": {
                    "lon": (r[0][0] + r[1][0]) / 2,
                    "lat": (r[0][1] + r[1][1]) / 2,
                }
            }
        )
        print(ifig.layout["mapbox"])
        return ifig
    return ifig

# Run app and display result inline in the notebook

app.run_server(mode="inline")

输出

相关问题