使用Plotly Express绘制人口普查数据Choropleth地图时变量失效问题
Plotly Choropleth地图无法渲染总人口变量(B01001_001E)
问题描述
使用Plotly Express结合censusdis包获取2022年ACS5人口普查数据制作交互式Choropleth地图时,家庭收入中位数(B19013_001E)、租金中位数(B25058_001E)可正常渲染地图,但总人口变量(B01001_001E)仅显示色阶,地图区域不显示。数据框的geometry列与正常变量返回内容一致。
复现代码
import plotly.express as px import censusdis.data as ced from censusdis.datasets import ACS5 #variable = 'B19013_001E' # 可正常工作 - 家庭收入中位数 #variable = 'B25058_001E' # 可正常工作 - 租金中位数 variable = 'B01001_001E' # 无法工作!总人口 df = ced.download( dataset=ACS5, vintage=2022, download_variables=['NAME', variable], state='06', county='075', tract='*', with_geometry=True) df = df.set_index('NAME') print(df.head()) fig = px.choropleth_mapbox(df, geojson=df.geometry, locations=df.index, center={'lat': 37.74180915, 'lon': -122.38474831884692}, color=variable, color_continuous_scale="Viridis", mapbox_style="carto-positron", opacity=0.5, zoom=10) fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) fig.show()
问题原因及解决建议
可能原因1:数据类型异常或存在无效值
B01001_001E作为总人口变量,可能被censusdis以非数值类型(如字符串)返回,或包含缺失值、无效标记(如-、N/A),导致Plotly无法识别为可渲染的数值数据。
解决步骤:
检查数据类型和有效值
运行以下代码确认变量的数据类型和是否存在空值:print(f"变量数据类型:{df[variable].dtype}") print(f"空值数量:{df[variable].isna().sum()}") print(f"唯一值示例:{df[variable].unique()[:10]}")转换并清理数据
如果数据为字符串类型或包含无效值,将其转换为数值并处理空值:import pandas as pd # 转换为数值,无法转换的设为NaN df[variable] = pd.to_numeric(df[variable], errors='coerce') # 删除包含空值的行 df = df.dropna(subset=[variable])
可能原因2:数值范围过大导致色阶异常
总人口的数值范围可能远大于收入、租金变量,导致Plotly的色阶拉伸过度,地图区域颜色差异极小,看起来像是未渲染。
解决步骤:
在px.choropleth_mapbox中手动设置颜色范围,使色阶适配总人口的数值区间:
fig = px.choropleth_mapbox(df, geojson=df.geometry, locations=df.index, center={'lat': 37.74180915, 'lon': -122.38474831884692}, color=variable, color_continuous_scale="Viridis", mapbox_style="carto-positron", opacity=0.5, zoom=10, # 设置颜色范围为变量的最小到最大值 range_color=[df[variable].min(), df[variable].max()])
可能原因3:GeoJSON与索引匹配问题
虽然geometry列看起来正常,但部分tract的NAME索引可能与GeoJSON的内部标识不匹配,导致Plotly无法关联数据与地图区域。
解决步骤:
改用censusdis返回的地理编码字段(如TRACT)作为locations参数,替代NAME索引:
# 不要设置NAME为索引,保留原始字段 # df = df.set_index('NAME') fig = px.choropleth_mapbox(df, geojson=df.geometry, locations='TRACT', # 使用tract编码作为匹配键 featureidkey="properties.TRACT", # 指定GeoJSON中的匹配字段 center={'lat': 37.74180915, 'lon': -122.38474831884692}, color=variable, color_continuous_scale="Viridis", mapbox_style="carto-positron", opacity=0.5, zoom=10)
内容的提问来源于stack exchange,提问作者Ari
相关产品推荐
相关产品推荐

