将 geopandas 边界图添加到 plotly

Adding geopandas boundary plot to plotly

我有两个独立的地图,一个是一个国家的文化边界(就像国家边界),以基于纬度和经度值的自定义多边形形式出现,以 geojson 格式定义。我可以使用 geopandas 轻松绘制多边形:

states = gpd.read_file('myfile.geojson')
states.boundary.plot()

这是一个示例输出:

第二个是我需要在地图图层上绘制的一系列具有相应值的纬度和经度,我可以使用 plotly express scatter_mapbox:

fig = px.scatter_mapbox(df_year,
                        lat='y', lon='x',
                        color='drought_index',
                        range_color=(-4, 4),
                        hover_data={'x': False, 'y': False},
                        zoom=5, height=800, width=1050,
                        center={'lat': 32.7089, 'lon': 53.6880},
                        color_continuous_scale=px.colors.diverging.RdYlGn,
                        color_continuous_midpoint=0,
                        )
fig.update_layout(mapbox_style="outdoors", mapbox_accesstoken=mb_token)

看起来像这样:

有什么方法可以将这两个图加在一起,让散点和形状边界在一张地图上重叠吗?这意味着在 mapbox 层的顶部,我可以看到散点和多边形的边界。

问题是 geopandas plot 使用 matplotlib 和 returens AxesSubplot:,我找不到任何方法将其添加到 plotly fig 中。我尝试了 plotly.tools 中的 mpl_to_plotly(),但它在 'Canvas is null'.

上引发了异常

我也试图找到一种方法来绘制 geojson 形状 plotly,但我能找到的只是 choropleth mapbox,它需要用颜色填充形状。无论如何,我都试图通过降低等值线图的不透明度来使用它,但它要么会覆盖散点图,要么几乎不可见。

如有任何关于如何解决此问题的建议,我们将不胜感激。

  • 您确实描述了解决方案。 https://plotly.com/python/mapbox-layers/
  • 已使用英国县边界作为 文化
  • 曾使用英国医院生成散点图框
  • "source": json.loads(gdf.geometry.to_json()), 确实是从 geopandas dataframe
  • 添加 GEOJSON 层的解决方案
import requests
import geopandas as gpd
import pandas as pd
import json, io
import plotly.express as px

# UK admin area boundaries
res = requests.get("https://opendata.arcgis.com/datasets/69dc11c7386943b4ad8893c45648b1e1_0.geojson")

# geopandas dataframe of "cultural layer"
gdf = gpd.GeoDataFrame.from_features(res.json()["features"], crs="CRS84")

# get some public addressess - hospitals.  data that can be scattered
dfhos = pd.read_csv(io.StringIO(requests.get("http://media.nhschoices.nhs.uk/data/foi/Hospital.csv").text),
    sep="¬",engine="python",)


fig = (
    px.scatter_mapbox(
        dfhos.head(100),
        lat="Latitude",
        lon="Longitude",
        color="Sector",
        hover_data=["OrganisationName", "Postcode"],
    )
    .update_traces(marker={"size": 10})
    .update_layout(
        mapbox={
            "style": "open-street-map",
            "zoom": 5,
            "layers": [
                {
                    "source": json.loads(gdf.geometry.to_json()),
                    "below": "traces",
                    "type": "line",
                    "color": "purple",
                    "line": {"width": 1.5},
                }
            ],
        },
        margin={"l": 0, "r": 0, "t": 0, "b": 0},
    )
)
fig.show()