You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Plotly go.Choroplethmapbox()基于SHP文件绘制Choropleth地图?

解决Plotly Choroplethmapbox加载自定义SHP/GeoJSON空白的问题

我看了你这段代码,问题主要出在几个容易忽略的细节上——尤其是地理数据的坐标参考系(CRS)和ID匹配逻辑,这俩是自定义地理数据在Plotly Mapbox里不显示的常见坑。咱们一步步来修复:

核心问题分析与修复步骤

1. 转换坐标参考系(最关键的问题)

你用到的芬兰 postal 区域SHP文件大概率采用的是**ETRS-TM35FIN(EPSG:3067)**本地坐标系,但Plotly的Mapbox只支持WGS84(EPSG:4326)的经纬度坐标。直接转GeoJSON不做坐标系转换的话,地图会因为坐标不在可视范围里显示空白。

修复代码:

# 读取SHP后立刻转换到WGS84坐标系
geodf = gpd.read_file('data/postal-areas-2021/PKS_postinumeroalueet_2021_shp.shp')
geodf = geodf.to_crs(epsg=4326)  # 这一步必须加!
geodf.to_file("data.geojson", encoding='utf-8', driver="GeoJSON")

2. 指定ID匹配的字段路径

你用locations=df['Posno']来关联地理区域和数值,但Plotly不知道在GeoJSON的哪个属性里找这个ID,必须通过featureidkey参数明确指定匹配的字段路径。

修复代码:在Choroplethmapbox里添加

featureidkey="properties.Posno"

3. 修正z值范围(避免颜色异常)

你生成的随机值是1-100,但设置了zmax=12,这会导致大部分值超出范围,颜色统一成最高色,看起来可能和预期不符。建议把z范围和数值范围匹配:

zmin=1,
zmax=100,

完整修正后的代码

import json
import random
import pandas as pd
import geopandas as gpd
import plotly.graph_objects as go

# 读取SHP并转换到Mapbox支持的WGS84坐标系
geodf = gpd.read_file('data/postal-areas-2021/PKS_postinumeroalueet_2021_shp.shp')
geodf = geodf.to_crs(epsg=4326)
geodf.to_file("data.geojson", encoding='utf-8', driver="GeoJSON")

# 加载转换后的GeoJSON
with open("data.geojson", encoding='utf-8') as geofile:
    counties = json.load(geofile)

# 生成匹配的数值DataFrame(简化写法)
df = pd.DataFrame({
    'Posno': [feat['properties']['Posno'] for feat in counties['features']],
    'rand': [random.randint(1, 100) for _ in counties['features']]
})

# 创建Choroplethmapbox图表
fig = go.Figure(go.Choroplethmapbox(
    geojson=counties,
    locations=df['Posno'],
    z=df['rand'],
    featureidkey="properties.Posno",  # 指定ID匹配字段
    colorscale="Viridis",
    zmin=1,
    zmax=100,
    marker_line_width=0.5,  # 调小线宽避免遮挡区域
    marker_opacity=0.7
))

# 更新地图布局
fig.update_layout(
    mapbox_style="open-street-map",
    height=1000,
    autosize=True,
    margin={"r":0,"t":0,"l":0,"b":0},
    paper_bgcolor='#303030',
    plot_bgcolor='#303030',
    mapbox=dict(
        center=dict(lat=60.1699, lon=24.9384),
        zoom=11
    )
)

fig.show()

额外调试技巧

  • 可以打印geodf.crs确认坐标系转换成功,输出应为EPSG:4326
  • 检查GeoJSON的feature结构,确保properties.Posno的格式和df里的Posno一致(比如都是字符串或整数,不要混合类型)
  • 如果还是有问题,先尝试用go.Choropleth(非Mapbox版本)测试地理数据是否能正常显示,排除GeoJSON本身的错误

内容的提问来源于stack exchange,提问作者Geom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 04:12:36