如何在Plotly中复刻人口密度地图的Choropleth颜色刻度?
复刻美国县人口密度地图的颜色刻度问题
我想复刻某张美国县人口密度地图的颜色刻度,核心需求是展现人口密度低于1000的县的颜色差异,但目前这些低数值县的颜色被高数值异常值冲淡,区分度很差。
我已经尝试过以下方法,但都没能成功复刻目标刻度:
- 使用Plotly的
px.choropleth中的range_color参数 - 自定义颜色刻度
- 用在线颜色刻度工具生成色阶
这是我目前的最佳效果:
希望能实现低数值区间更平缓的颜色渐变,求帮助。
解决思路与代码示例
1. 对数变换压缩高值区间
人口密度属于典型的幂律分布,少数县密度极高,直接用线性刻度会挤压低数值区间的颜色空间。对密度值做对数变换,能让低数值区间的颜色差异更明显:
import plotly.express as px import pandas as pd import numpy as np # 假设数据框df包含'fips'(县编码)和'density'(人口密度)列 df['log_density'] = df['density'].apply(lambda x: max(1, x)).apply(np.log10) # 规避0值对数报错 fig = px.choropleth(df, locations='fips', locationmode='USA-states', color='log_density', scope='usa', color_continuous_scale='YlOrRd', # 贴近目标图的暖色调 color_continuous_midpoint=np.log10(1000) # 锚定1000的颜色位置 ) # 把对数刻度转回原始数值显示,提升可读性 fig.update_layout(coloraxis_colorbar=dict( tickvals=[np.log10(1), np.log10(10), np.log10(100), np.log10(1000), np.log10(10000)], ticktext=['1', '10', '100', '1000', '10000'] )) fig.show()
2. 手动分段自定义色阶
如果对数变换不符合需求,可以手动划分数值区间,给低数值段分配更多颜色梯度:
# 自定义色阶,低数值区间用更平缓的渐变 color_scale = [ [0, '#ffffcc'], [0.2, '#ffeda0'], [0.4, '#fed976'], [0.6, '#feb24c'], [0.8, '#fd8d3c'], [0.95, '#fc4e2a'], [1, '#e31a1c'] ] # 重点划分<1000的区间,高值区间合并 bins = [0, 10, 50, 100, 500, 1000, 5000, 200000] df['density_bin'] = pd.cut(df['density'], bins=bins, labels=False) fig = px.choropleth(df, locations='fips', locationmode='USA-states', color='density_bin', scope='usa', color_continuous_scale=color_scale, color_continuous_midpoint=3 ) fig.update_layout(coloraxis_colorbar=dict( tickvals=[0,1,2,3,4,5,6], ticktext=['0-10','10-50','50-100','100-500','500-1000','1000-5000','>5000'] )) fig.show()
3. 给色阶绑定具体数值锚点
直接将颜色刻度与实际数值绑定,确保低数值区间有足够的颜色变化空间:
# 把颜色和具体密度值绑定,低数值区间分配更多色阶节点 custom_scale = [ (0, '#ffffcc'), # 0 (10/200000, '#ffeda0'), # 10 (100/200000, '#fed976'), # 100 (500/200000, '#feb24c'), # 500 (1000/200000, '#fd8d3c'),# 1000 (5000/200000, '#fc4e2a'),# 5000 (1, '#e31a1c') # 最大值 ] fig = px.choropleth(df, locations='fips', locationmode='USA-states', color='density', scope='usa', color_continuous_scale=custom_scale, range_color=[0, 200000] ) fig.show()
内容的提问来源于stack exchange,提问作者hannes
相关产品推荐
相关产品推荐

