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

Python中Plotly Choropleth地图不显示问题求助(附代码)

问题:Plotly Choropleth地图仅显示图例,地图区域无法渲染

我在Python环境中用Folium和Plotly制作Choropleth地图,数据取自CBS开放数据平台。Folium生成的地图可正常展示,但Plotly版本只显示图例,地图区域完全不显示,以下是实现代码:

#Make choropleth map with folium and with plotly

#CBS Open Data
#https://www.cbs.nl/nl-nl/onze-diensten/open-data/statline-als-open-data/cartografie

#Plotly
#https://plotly.com/python/mapbox-county-choropleth/


#Libraries
import pandas as pd
import geopandas as gpd
import folium
import cbsodata
import plotly.express as px

# Find out which columns are available
metadata = pd.DataFrame(cbsodata.get_meta('83765NED', 'DataProperties'))

# Download birth rates and delete spaces from regional identifiers
data = pd.DataFrame(cbsodata.get_data('83765NED', select = ['WijkenEnBuurten', 'Codering_3', 'GeboorteRelatief_25']))
data['Codering_3'] = data['Codering_3'].str.strip()

# Retrieve data with municipal boundaries from PDOK
geodata_url = 'https://cartomap.github.io/nl/wgs84/gemeente_2023.geojson'
municipal_boundaries = gpd.read_file(geodata_url)

# Link data from Statistics Netherlands to geodata
municipal_boundaries = pd.merge(municipal_boundaries, data,
                               left_on = "statcode", 
                               right_on = "Codering_3")

#CRS: EPSG 3857 (web mercator projection wgs84)
municipal_boundaries.crs
municipal_boundaries = municipal_boundaries.to_crs(epsg = 3857)


#First column: Geoid, geometry column and  data columns
gdf_choro = municipal_boundaries.copy()
gdf_choro['geoid'] = gdf_choro.index.astype(str)
gdf_choro = gdf_choro[['geoid', 'geometry', 'statnaam', 'GeboorteRelatief_25']]
gdf_choro.head(3)

#Center
nld_lat = 52.2130
nld_lon = 5.2794
nld_coordinates = (nld_lat, nld_lon)

#Folium base map
map_nld = folium.Map(location=nld_coordinates, tiles='cartodbpositron', zoom_start=6, control_scale=True)

#Folium choropleth
map_nld = folium.Map(location=nld_coordinates, tiles='cartodbpositron', zoom_start=6, control_scale=True)
folium.Choropleth(geo_data=gdf_choro,
                  data=gdf_choro,
                  columns=['geoid', 'GeboorteRelatief_25'],
                  key_on='feature.id',
                  fill_color='Blues',                  
                  legend_name='Geboorterelatief'
                 ).add_to(map_nld)
map_nld

#Plotly choropleth
fig = px.choropleth_mapbox(gdf_choro,
                           geojson=gdf_choro['geometry'],
                           locations=gdf_choro.geoid,
                           color='GeboorteRelatief_25',
                           center={'lat': 52.213, 'lon':5.2794},
                           mapbox_style='cartodbpositron',
                           zoom=6)
fig.show()

问题排查与修复方案

核心问题点

  1. 坐标系不兼容:Plotly的choropleth_mapbox依赖Mapbox,要求地理数据必须是**WGS84(EPSG:4326)**坐标系,你之前转成了EPSG:3857,导致地图无法正确渲染。
  2. GeoJSON参数传递错误:geojson参数需要传入完整的GeoDataFrame对象(或其__geo_interface__属性),而不是单独提取geometry列。
  3. 关联字段不可靠:用索引生成的geoid无法和GeoJSON中的属性字段对应,建议直接用区域编码statcode作为关联键。

修复后的完整代码

import pandas as pd
import geopandas as gpd
import folium
import cbsodata
import plotly.express as px

# 获取元数据
metadata = pd.DataFrame(cbsodata.get_meta('83765NED', 'DataProperties'))

# 下载出生率数据并清理区域编码
data = pd.DataFrame(cbsodata.get_data('83765NED', select=['WijkenEnBuurten', 'Codering_3', 'GeboorteRelatief_25']))
data['Codering_3'] = data['Codering_3'].str.strip()

# 获取荷兰市政边界数据(默认是WGS84坐标系)
geodata_url = 'https://cartomap.github.io/nl/wgs84/gemeente_2023.geojson'
municipal_boundaries = gpd.read_file(geodata_url)

# 关联CBS数据与地理数据
municipal_boundaries = pd.merge(municipal_boundaries, data, left_on="statcode", right_on="Codering_3")

# --- Folium部分保持不变 ---
nld_lat = 52.2130
nld_lon = 5.2794
nld_coordinates = (nld_lat, nld_lon)

map_nld = folium.Map(location=nld_coordinates, tiles='cartodbpositron', zoom_start=6, control_scale=True)
folium.Choropleth(
    geo_data=municipal_boundaries,
    data=municipal_boundaries,
    columns=['statcode', 'GeboorteRelatief_25'],
    key_on='feature.properties.statcode',
    fill_color='Blues',
    legend_name='Geboorterelatief'
).add_to(map_nld)
# map_nld  # 如需显示Folium地图可取消注释

# --- Plotly修复部分 ---
# 无需转换坐标系,保持原始WGS84(EPSG:4326)
fig = px.choropleth_mapbox(
    municipal_boundaries,
    geojson=municipal_boundaries.__geo_interface__,  # 传入完整GeoJSON结构
    locations='statcode',  # 用statcode作为关联键,对应GeoJSON中的properties.statcode
    color='GeboorteRelatief_25',
    color_continuous_scale='Blues',
    center={'lat': nld_lat, 'lon': nld_lon},
    mapbox_style='cartodbpositron',
    zoom=6,
    hover_name='statnaam'  # 鼠标悬停显示区域名称
)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})  # 去除边距
fig.show()

关键修改说明

  • 移除了将地理数据转成EPSG:3857的代码,保留原始WGS84坐标系。
  • Plotly部分的geojson参数改用municipal_boundaries.__geo_interface__,确保传入完整的GeoJSON结构。
  • locations参数改用statcode,与GeoJSON属性中的statcode字段对应,保证数据和地理区域正确关联。
  • 添加了hover_name和边距优化,提升交互体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:52:55