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()
问题排查与修复方案
核心问题点
- 坐标系不兼容:Plotly的
choropleth_mapbox依赖Mapbox,要求地理数据必须是**WGS84(EPSG:4326)**坐标系,你之前转成了EPSG:3857,导致地图无法正确渲染。 - GeoJSON参数传递错误:
geojson参数需要传入完整的GeoDataFrame对象(或其__geo_interface__属性),而不是单独提取geometry列。 - 关联字段不可靠:用索引生成的
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
相关产品推荐
相关产品推荐

