Plotly绘制多边形/多多边形时部分区域背景异常着色问题求助
问题描述
使用Geopandas和Plotly绘制地图数据,已完成数据解析与合并,但绘图时约三分之一的图形未正常内部着色,反而填充了整个背景。排查发现异常图形多为Multipolygon类型,但也存在能正常渲染的Multipolygon。
- 正常渲染效果:

- 异常渲染效果:

原始代码如下:
import pandas as pd import plotly.express as px import geopandas as gpd import pyproj # 读取shapefile map_df = gpd.read_file("mn-cd6-precincts.json") map_df.to_crs(pyproj.CRS.from_epsg(4326), inplace=True) # 加载选民数据 df = pd.read_csv("voting_by_precinct.csv") # 统一PrecinctID类型以便合并 map_df["PrecinctID"] = map_df["PrecinctID"].astype(str) df["PrecinctID"] = df["PrecinctID"].astype(str) # 合并数据 merged = pd.merge(map_df, df, how='left', on='PrecinctID') # 绘制地图 fig = px.choropleth(merged, geojson=merged.geometry, locations=merged.index, color="PrecinctID") # 设置初始视图范围 fig.update_geos(fitbounds="locations", visible=False) fig.update_traces(marker_line_width=1) fig.show()
更新补充:
- 位置数据(JSON格式)
- 计数数据(CSV格式)
解决方法
这种异常通常是几何图形的顶点顺序错误导致的:Plotly遵循右手定则,若多边形顶点为顺时针排列,会被识别为“外部环”,从而填充整个地图背景而非多边形内部;部分Multipolygon可能存在子多边形(内环/外环)顺序或方向错误的问题。
步骤1:修复几何图形有效性
使用Geopandas的buffer(0)方法自动修复多边形方向、自相交等问题,对Multipolygon同样适用:
# 在数据合并后添加几何修复步骤 merged['geometry'] = merged['geometry'].buffer(0) # 复杂无效几何可使用make_valid()方法 merged['geometry'] = merged['geometry'].make_valid()
步骤2:确认CRS正确性
确保几何数据的CRS为WGS84(EPSG:4326),显式转换并验证:
merged = merged.to_crs(epsg=4326) # 检查几何有效性分布 print(merged.geometry.is_valid.value_counts())
步骤3:优化Plotly调用参数
指定featureidkey明确关联数据与GeoJSON,避免索引匹配问题:
fig = px.choropleth(merged, geojson=merged.geometry, locations=merged.index, color="PrecinctID", featureidkey="properties.index") # 明确数据关联键
修改后的完整代码
import pandas as pd import plotly.express as px import geopandas as gpd # 读取并处理地理数据 map_df = gpd.read_file("mn-cd6-precincts.json") map_df = map_df.to_crs(epsg=4326) # 显式转换CRS # 加载并处理选民数据 df = pd.read_csv("voting_by_precinct.csv") map_df["PrecinctID"] = map_df["PrecinctID"].astype(str) df["PrecinctID"] = df["PrecinctID"].astype(str) # 合并数据并修复几何 merged = pd.merge(map_df, df, how='left', on='PrecinctID') merged['geometry'] = merged['geometry'].buffer(0) # 修复几何方向与有效性 # 绘制地图 fig = px.choropleth(merged, geojson=merged.geometry, locations=merged.index, color="PrecinctID", featureidkey="properties.index") fig.update_geos(fitbounds="locations", visible=False) fig.update_traces(marker_line_width=1) fig.show()
额外排查点
若问题仍存在:
- 筛选无效几何:
invalid_geoms = merged[~merged.geometry.is_valid],定位具体异常的PrecinctID - 手动调整Multipolygon子多边形顺序,确保外环在前、内环在后
内容的提问来源于stack exchange,提问作者JPatrick
相关产品推荐
相关产品推荐

