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

Plotly子图中绘制GeoDataFrame Choropleth地图报错求助

Plotly子图中绘制GeoDataFrame Choropleth地图报错求助

嗨,我来帮你解决这个问题~你遇到的TypeError: Object of type Polygon is not JSON serializable报错,核心原因是Plotly Express的px.choropleth会自动帮你把GeoDataFrame的几何对象转换成GeoJSON格式,但go.Choroplethmapbox需要你手动传入标准的GeoJSON字符串,而不是直接用DataFrame里的Polygon对象。

下面是具体的解决步骤和完整代码示例:

第一步:把GeoDataFrame转换成GeoJSON字符串

GeoDataFrame自带to_json()方法,可以直接把整个数据集转换成符合规范的GeoJSON格式字符串,这是让Choroplethmapbox能识别的关键:

# 将GeoDataFrame转为GeoJSON字符串
geojson_data = s_new_cp.to_json()

第二步:在子图中添加Choroplethmapbox trace

这里要注意两个关键参数:

  • featureidkey:指定GeoJSON中用来和你的DataFrame数据匹配的属性字段(比如你的DataFrame里的area列,在GeoJSON的properties里会有对应的字段)
  • locations:传入DataFrame中用来匹配的列(比如area列)

完整的子图代码示例:

import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 创建子图布局,指定两个mapbox类型的子图
p5 = make_subplots(rows=1, cols=2, specs=[[{"type":"mapbox"},{"type":"mapbox"}]])

# 第一个子图:绘制usage字段的 choropleth 地图
p5.add_trace(go.Choroplethmapbox(
    geojson=geojson_data,
    locations=s_new_cp["area"],  # 对应GeoJSON properties里的area字段
    z=s_new_cp["usage"],         # 要可视化的数值列
    featureidkey="properties.area",  # 设置匹配的GeoJSON属性字段
    colorscale="Viridis",
    zmin=0,
    zmax=1,
    colorbar_title="Usage"
), row=1, col=1)

# 第二个子图:绘制estimate字段的 choropleth 地图(你可以换成自己需要的列)
p5.add_trace(go.Choroplethmapbox(
    geojson=geojson_data,
    locations=s_new_cp["area"],
    z=s_new_cp["estimate"],
    featureidkey="properties.area",
    colorscale="Plasma",
    zmin=0,
    zmax=1,
    colorbar_title="Estimate"
), row=1, col=2)

# 设置地图样式和中心点(用数据的几何中心自动计算)
p5.update_layout(
    mapbox_style="carto-positron",  # 用免费的公开地图样式,无需token
    mapbox_zoom=6,
    mapbox_center={
        "lat": s_new_cp.geometry.centroid.y.mean(),
        "lon": s_new_cp.geometry.centroid.x.mean()
    }
)

# 调整整体布局,避免元素重叠
p5.update_layout(
    height=600,
    width=1000,
    title_text="区域指标对比地图"
)

# 显示地图
p5.show()

额外说明:如果想用DataFrame的index作为匹配字段

如果你更习惯用index来匹配数据,可以先把index转换成DataFrame的一列,再生成GeoJSON:

# 把index转为名为id的列
s_new_cp_with_idx = s_new_cp.reset_index().rename(columns={"index": "id"})
geojson_data = s_new_cp_with_idx.to_json()

# 后续trace中设置:
# locations=s_new_cp_with_idx["id"],
# featureidkey="properties.id"

这样调整后,你就能顺利在Plotly子图中绘制GeoDataFrame的 choropleth 地图啦~

备注:内容来源于stack exchange,提问作者imantha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 14:59:31