如何使用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
相关产品推荐
相关产品推荐

