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

如何用gv.Polygons替代gv.Shape绘制英国行政区划Choropleth地图

解决方案:Geoviews绘制LAD19联动地图(两种路径)

看起来你卡在Geoviews几何对象维度错误和联动功能实现上了,我之前处理英国行政区数据时也踩过类似的坑,给你两个可行的解决方案:


路径一:修复gv.Polygons的DataError并实现联动

你的DataError几乎可以肯定是GeoDataFrame里的几何对象带了三维Z坐标——OSGB(27700)的LAD19 shp文件经常会附带不必要的Z维度,而gv.Polygons只支持二维平面几何。按以下步骤修复:

1. 先把几何转成二维

用GeoPandas的to_2d()方法直接移除Z坐标:

import geopandas as gpd
import geoviews as gv
import pandas as pd
import hvplot.pandas

# 加载并预处理数据
gdf = gpd.read_file("LAD19_shapefile.shp")
# 检查是否有Z坐标(可选)
print(gdf.geometry.has_z.unique())
# 转换为二维几何
gdf["geometry"] = gdf["geometry"].to_2d()

# 合并人口数据(确保用唯一关联键,比如LAD19CD)
population_df = pd.read_csv("population_data.csv")
merged_gdf = gdf.merge(population_df, on="LAD19CD", how="left").dropna(subset=["population"])

2. 正确初始化gv.Polygons并绑定联动

指定唯一标识的kdims(行政区代码)和着色用的vdims(人口数),再绑定点击事件到右侧表格:

# 创建Polygons交互式图层
lad_polygons = gv.Polygons(merged_gdf, kdims=["LAD19CD"], vdims=["population", "LAD19NM"]).opts(
    tools=["tap", "hover"],
    color="population",
    cmap="viridis",
    colorbar=True,
    width=800,
    height=600,
    title="英国LAD19行政区人口分布"
)

# 定义联动表格生成函数
from bokeh.models.widgets import DataTable, TableColumn

def render_selected_table(selected_data):
    if not selected_data:
        return DataTable(columns=[], data=[])
    # 获取选中的行政区数据
    selected_cd = selected_data["LAD19CD"][0]
    selected_row = merged_gdf[merged_gdf["LAD19CD"] == selected_cd].to_dict("records")[0]
    # 定义表格列
    columns = [
        TableColumn(field="LAD19NM", title="行政区名称"),
        TableColumn(field="population", title="人口数"),
        TableColumn(field="LAD19CD", title="行政区代码")
    ]
    return DataTable(columns=columns, data=[selected_row])

# 绑定点击事件到表格
linked_table = hvplot.bind(render_selected_table, lad_polygons.data).widgets()

# 组合地图和表格显示
lad_polygons + linked_table

路径二:直接实现gv.Shape的联动功能

如果不想切换到gv.Polygons,gv.Shape完全可以实现联动,核心是利用Holoviews的Selection1D流来绑定选择事件:

1. 初始化gv.Shape图层

同样先确保几何是二维,然后启用交互工具:

import holoviews as hv
hv.extension("bokeh")

# 复用之前预处理好的merged_gdf
lad_shape = gv.Shape(merged_gdf, kdims=["LAD19CD"], vdims=["population", "LAD19NM"]).opts(
    tools=["tap", "hover"],
    color="population",
    cmap="viridis",
    width=800,
    height=600
)

2. 绑定选择事件到图表/表格

比如绑定到一个柱状图,显示选中行政区的人口数据:

# 定义联动更新函数
def update_chart(selected_indices):
    if not selected_indices:
        return hv.Bars([]).opts(title="请选择一个行政区")
    # 获取选中行的行政区代码
    selected_cd = merged_gdf.iloc[selected_indices]["LAD19CD"].iloc[0]
    selected_data = merged_gdf[merged_gdf["LAD19CD"] == selected_cd]
    # 返回柱状图(可以扩展为对比多个数据,比如和全国平均)
    return hv.Bars(selected_data, kdims="LAD19NM", vdims="population").opts(
        width=400, height=300, title="选中行政区人口"
    )

# 绑定选择流:tap事件触发更新
linked_chart = hv.DynamicMap(update_chart, streams=[hv.streams.Selection1D(source=lad_shape)])

# 组合地图和图表
lad_shape + linked_chart

关键注意事项

  1. 无论哪种方法,必须确保几何是二维:用gdf.geometry.has_z检查,有Z值就用to_2d()转换
  2. 联动的核心是kdims必须是唯一标识列(比如LAD19CD),这样选中事件才能精准关联数据
  3. 合并数据后记得清理空值:用dropna(subset=["population"])避免渲染错误

内容的提问来源于stack exchange,提问作者mmTmmR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 23:18:10