使用Plotly Graph Objects绘制人口普查数据时的JSON序列化错误解决
修复Plotly Graph Objects Choroplethmapbox的JSON序列化错误
问题根源
Plotly Express的choropleth_mapbox会自动处理Shapely几何对象(Polygon/MultiPolygon)的序列化,但Plotly Graph Objects的Choroplethmapbox组件无法直接识别Shapely对象,必须手动将其转换为GeoJSON格式才能正常解析。
修复步骤
- 检查地理数据类型:确认数据集里的地理字段是Shapely的
Polygon或MultiPolygon对象,这是报错的直接原因。 - 转换为GeoJSON格式:通过GeoPandas或Shapely工具将几何对象转为GeoJSON结构,这是Graph Objects能识别的格式。
- 调整图表参数:将转换后的GeoJSON传入
geojson参数,同时确保locations参数对应GeoJSON中包含的属性字段(如县的GEOID或名称)。
具体代码示例
方法1:用GeoPandas快速转换
import plotly.graph_objects as go import geopandas as gpd # 加载包含地理数据的纽约县人口普查数据 nyc_census = gpd.read_file("nyc_census_counties.shp") # 替换为你的数据源 # 将GeoDataFrame转为GeoJSON字符串 geojson_data = nyc_census.to_json() # 提取匹配字段和数值字段 locations = nyc_census["GEOID"] # GeoJSON属性中的匹配键 population_values = nyc_census["total_population"] # 创建Choroplethmapbox图表 fig = go.Figure(go.Choroplethmapbox( geojson=geojson_data, locations=locations, z=population_values, colorscale="YlOrRd", colorbar_title="总人口", marker_opacity=0.6, marker_line_width=0.3 )) # 设置地图布局 fig.update_layout( mapbox_style="carto-darkmatter", mapbox_zoom=9.5, mapbox_center={"lat": 40.7128, "lon": -74.0060}, margin={"r":0,"t":0,"l":0,"b":0} ) fig.show()
方法2:手动转换Shapely对象(无GeoPandas时)
import plotly.graph_objects as go import pandas as pd from shapely.geometry import mapping # 假设你的数据存储在普通DataFrame中,包含geometry列(Shapely对象)和人口数据 df = pd.read_csv("nyc_census_data.csv") # 替换为你的数据源 # 构建GeoJSON FeatureCollection features = [] for _, row in df.iterrows(): feature = { "type": "Feature", "properties": {"county_name": row["county_name"]}, # 匹配字段 "geometry": mapping(row["geometry"]) } features.append(feature) geojson_data = {"type": "FeatureCollection", "features": features} # 创建图表 fig = go.Figure(go.Choroplethmapbox( geojson=geojson_data, locations=df["county_name"], z=df["total_population"], colorscale="Viridis", colorbar_title="总人口" )) fig.update_layout( mapbox_style="open-street-map", mapbox_zoom=9, mapbox_center={"lat": 40.7128, "lon": -74.0060}, margin={"r":0,"t":0,"l":0,"b":0} ) fig.show()
关键说明
Plotly Express在底层会自动调用GeoPandas的序列化逻辑,帮你把Shapely对象转成GeoJSON;而Graph Objects作为更底层的API,需要开发者手动完成这一步转换,避免JSON序列化失败。
内容的提问来源于stack exchange,提问作者Ankur
相关产品推荐
相关产品推荐

