Plotly Choropleth Mapbox无法正确渲染GeoJSON:映射/几何问题排查
解决Plotly choropleth_mapbox电力竞价区域渲染及交互问题
一、修复投影转换失效问题
投影错误是地图显示随机形状的核心原因,按以下步骤确保转换生效:
- 加载Shapefile时强制指定原CRS:GeoPandas若无法自动识别Shapefile的投影(无.prj文件),重投影会直接失效。先确认原数据的EPSG代码(比如欧洲常用的EPSG:3035),再执行:
import geopandas as gpd # 加载并指定原CRS gdf = gpd.read_file("bidding_zones.shp") if gdf.crs is None: gdf = gdf.set_crs("EPSG:3035") # 替换为你的原投影EPSG代码 # 重投影至WGS84(EPSG:4326) gdf = gdf.to_crs("EPSG:4326")
- 验证转换结果:打印
gdf.geometry.head(),确认坐标值在±180(经度)、±90(纬度)范围内,而非大数值的投影坐标。 - 正确导出GeoJSON:用GeoPandas内置方法避免手动处理出错:
geojson_data = gdf[["zoneName", "geometry"]].to_json()
二、修复代码变量与语法错误
- 定义匹配的测试数据:确保
zoneName与GeoJSON中的字段完全一致(大小写、空格、缩写必须严格匹配),同时包含电价、年月字段:
import pandas as pd import numpy as np # 生成与GeoJSON匹配的测试数据 test_data = pd.DataFrame({ "zoneName": gdf["zoneName"].tolist(), "price": np.random.randint(0, 100, len(gdf)), "year": 2024, "month": np.random.randint(1, 13, len(gdf)) })
- 检查
choropleth_mapbox参数对应关系:核心参数必须精准匹配:geojson:传入转换后的GeoJSON字符串locations:数据中用于匹配的列(即zoneName)featureidkey:GeoJSON中属性的路径,固定为properties.zoneName
三、基础可渲染地图代码
import plotly.express as px fig = px.choropleth_mapbox( test_data, geojson=geojson_data, locations="zoneName", featureidkey="properties.zoneName", color="price", color_continuous_scale="Viridis", mapbox_style="carto-positron", zoom=3, center={"lat": 50, "lon": 10}, # 对应欧洲区域中心 opacity=0.7, labels={"price": "现货平均电价"} ) fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) fig.show()
四、添加年月筛选交互
通过Plotly的updatemenus实现下拉筛选,按年月组合过滤数据:
# 生成所有年月筛选选项 year_month_options = [] unique_years = test_data["year"].unique() for year in unique_years: sorted_months = sorted(test_data[test_data["year"] == year]["month"].unique()) for month in sorted_months: year_month_options.append( dict( label=f"{year}年{month}月", method="update", args=[ {"visible": (test_data["year"] == year) & (test_data["month"] == month)}, {"title": f"{year}年{month}月 电力现货平均电价"} ] ) ) # 集成筛选菜单到布局 fig.update_layout( updatemenus=[ dict( buttons=year_month_options, direction="down", showactive=True, x=0.1, xanchor="left", y=1.1, yanchor="top" ) ], title="电力竞价区域现货平均电价" ) fig.show()
关键排查要点
- 字段匹配:
zoneName在数据和GeoJSON中必须完全一致,包括大小写、空格、特殊字符 - 投影验证:重投影后必须确认坐标为WGS84经纬度范围
- GeoJSON结构:用文本编辑器打开GeoJSON,确认
features[*].properties.zoneName存在且值正确
内容的提问来源于stack exchange,提问作者g3nkoVMAESTRO
相关产品推荐
相关产品推荐

