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

Altair transform_lookup绘制丹麦市政犯罪热力图失败求助

问题

我尝试绘制丹麦各市政区域的犯罪热力图,用颜色编码对应区域的犯罪总数。数据按时间周期和犯罪类型拆分,每个市政有多条记录,但仅对应一条几何数据。我希望通过label_dk键对GeoPandas数据框中的geometry字段执行transform_lookup操作,但地图始终无法渲染。

我本可合并数据框,但为节省空间避免重复存储几何数据(实际数据约3万条,合并后GeoJSON达647000KB导致地图无法渲染),同时需基于时间和犯罪类型做数据切片分析,因此想采用lookup方案。请问为何transform_lookup无法生效?

数据样例

几何数据(99行)

label_dk                                           geometry
0          Aabenraa  MULTIPOLYGON Z (((9.51215 54.85672 -999.00000,...
1           Aalborg  MULTIPOLYGON Z (((9.84688 57.04365 -999.00000,...
2            Aarhus  POLYGON Z ((9.99682 56.17872 -999.00000, 9.990...
3       Albertslund  POLYGON Z ((12.35234 55.70461 -999.00000, 12.3...
4           Allerød  POLYGON Z ((12.31845 55.88305 -999.00000, 12.3...
..              ...                                                ...
94            Vejle  POLYGON Z ((9.11714 55.76669 -999.00000, 9.100...
95  Vesthimmerlands  MULTIPOLYGON Z (((9.17798 56.91745 -999.00000,...
96           Viborg  POLYGON Z ((9.29501 56.59336 -999.00000, 9.297...
97      Vordingborg  MULTIPOLYGON Z (((12.04479 54.95566 -999.00000...
98              Ærø  MULTIPOLYGON Z (((10.43467 54.87952 -999.00000...

犯罪数据(792行)

tid                     offence   label_dk  Anmeldte forbrydelser
0    2021K1  Seksualforbrydelser i alt  København                    133
1    2021K1    Voldsforbrydelser i alt  København                    900
2    2021K2  Seksualforbrydelser i alt  København                    244
3    2021K2    Voldsforbrydelser i alt  København                    996
4    2021K3  Seksualforbrydelser i alt  København                    174
..      ...                        ...        ...                    ...
787  2021K2    Voldsforbrydelser i alt    Aalborg                    178
788  2021K3  Seksualforbrydelser i alt    Aalborg                     53
789  2021K3    Voldsforbrydelser i alt    Aalborg                    185
790  2021K4  Seksualforbrydelser i alt    Aalborg                     43
791  2021K4    Voldsforbrydelser i alt    Aalborg                    205

代码

import altair as alt
import geopandas as gpd
import pandas as pd
import altair_viewer


alt.data_transformers.enable('data_server')
path = "data/small_few_umbrella_terms_crimes_2021.csv"
df = pd.read_csv(path,encoding="utf_8",index_col='Unnamed: 0')

geometry = gpd.read_file("data_with_geo/geometry.geojson")


map_chart = alt.Chart(df).mark_geoshape(
).transform_aggregate(
    crime='sum(Anmeldte forbrydelser)',
    groupby=["label_dk"]
).transform_lookup(
    lookup='label_dk',
    from_=alt.LookupData(geometry, 'label_dk', ['geometry'])
).encode(
    color=alt.Color(
        "crime:Q",
        scale=alt.Scale(
            scheme='viridis')
    )
)

altair_viewer.show(map_chart)

解决方案

你的transform_lookup失效主要有两个核心原因,对应修复方法如下:

1. LookupData无法直接解析GeoPandas的地理对象

Altair的alt.LookupData无法识别GeoPandas数据框中geometry字段的地理空间对象类型,它需要序列化后的GeoJSON格式数据才能正确渲染图形。

修复方法:
将GeoDataFrame转换为普通Pandas数据框,并把geometry字段转为GeoJSON结构:

# 转换坐标系为Altair默认的WGS84(EPSG:4326),再将geometry转为GeoJSON
geometry_df = geometry.to_crs(epsg=4326).assign(
    geometry=lambda x: x.geometry.apply(lambda geom: geom.__geo_interface__)
)

2. 需确保匹配键完全一致

聚合后的label_dk与几何数据中的label_dk必须完全匹配(包括丹麦语特殊字符、大小写),否则会出现匹配失败,导致无几何数据可渲染。

完整修复代码

import altair as alt
import geopandas as gpd
import pandas as pd
import altair_viewer

alt.data_transformers.enable('data_server')
path = "data/small_few_umbrella_terms_crimes_2021.csv"
df = pd.read_csv(path, encoding="utf_8", index_col='Unnamed: 0')

# 读取并转换几何数据格式
geometry = gpd.read_file("data_with_geo/geometry.geojson")
geometry_df = geometry.to_crs(epsg=4326).assign(
    geometry=lambda x: x.geometry.apply(lambda g: g.__geo_interface__)
)

map_chart = alt.Chart(df).mark_geoshape(
).transform_aggregate(
    crime='sum(Anmeldte forbrydelser)',
    groupby=["label_dk"]
).transform_lookup(
    lookup='label_dk',
    from_=alt.LookupData(geometry_df, 'label_dk', ['geometry'])
).encode(
    color=alt.Color("crime:Q", scale=alt.Scale(scheme='viridis')),
    tooltip=['label_dk:N', 'crime:Q']  # 可选:添加悬浮显示信息
).properties(
    width=600,
    height=600
)

altair_viewer.show(map_chart)

额外优化建议

  • 如果要支持时间和犯罪类型的切片分析,可以添加交互选择器,结合transform_filter实现动态筛选:
    # 时间周期选择器示例
    tid_selector = alt.binding_select(options=df['tid'].unique())
    tid_select = alt.selection_single(fields=['tid'], bind=tid_selector, name='选择时间周期')
    
    map_chart = alt.Chart(df).mark_geoshape(
    ).add_selection(tid_select
    ).transform_filter(tid_select
    ).transform_aggregate(
        crime='sum(Anmeldte forbrydelser)',
        groupby=["label_dk"]
    ).transform_lookup(
        lookup='label_dk',
        from_=alt.LookupData(geometry_df, 'label_dk', ['geometry'])
    ).encode(
        color=alt.Color("crime:Q", scale=alt.Scale(scheme='viridis')),
        tooltip=['label_dk:N', 'crime:Q']
    )
    
  • 始终确保几何数据使用EPSG:4326坐标系,这是Altair地理图形的默认坐标系,避免出现位置偏移或不渲染问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 21:02:09