Plotly Express美国大选获胜差值地图:固定0值为白色的配色实现
固定0值为白色的红蓝双向发散美国大选地图配色方案
问题描述
我用Plotly Express绘制美国总统大选各州获胜差值(R_margin_x)的美国地图,需求如下:
- 获胜差值为0的区域显示为白色
- 配色向红色、蓝色双向发散
但color_continuous_scale参数的取值范围为0-1,且不同选举周期中,获胜差值0在该区间内的对应位置会变化。我尝试过将0转换为0-1区间的分数,但该值会随选举周期改变,现有实现代码如下:
fig = px.choropleth(merged, locationmode='USA-states', locations='state_po', animation_frame='year', color='R_margin_x', color_continuous_scale=[(0, 'blue'), (merged['R_margin_x'].min()/(merged['R_margin_x'].min()-merged['R_margin_x'].max()), 'white'), (1, 'red')], scope='usa') fig.show()
数据框格式示例:
party_simplified state_po year DEMOCRAT LIBERTARIAN OTHER REPUBLICAN D_pct_x L_pct_x O_pct_x R_pct_x R_margin_x D_pct_y L_pct_y O_pct_y R_pct_y R_margin_y R_lean 0 AK 2008 123594.0 1589.0 7173.0 193841.0 37.889374 0.487129 2.198978 59.424520 21.535146 52.761558 0.388418 1.488455 45.361569 -7.39999 28.935135 1 AL 2008 813479.0 NaN 19794.0 1266546.0 38.740434 NaN 0.942653 60.316913 21.576479 52.761558 0.388418 1.488455 45.361569 -7.39999 28.976468 2 AR 2008 422310.0 4776.0 21514.0 638017.0 38.864660 0.439529 1.979906 58.715904 19.851245 52.761558 0.388418 1.488455 45.361569 -7.39999 27.251234 3 AZ 2008 1034707.0 12555.0 16102.0 1230111.0 45.115251 0.547423 0.702079 53.635248 8.519997 52.761558 0.388418 1.488455 45.361569 -7.39999 15.919987 4 CA 2008 8274473.0 67582.0 208064.0 5011781.0 61.012638 0.498323 1.534180 36.954859 -24.057780 52.761558 0.388418 1.488455 45.361569 -7.39999 -16.657790
请问是否有可行方法,能固定0值为白色并实现红蓝双向发散的配色?
解决方案
方法1:使用color_continuous_midpoint参数(推荐)
Plotly Express的choropleth内置了color_continuous_midpoint参数,直接将其中值设为0,配合双向发散的配色列表,就能让0值稳定对应白色,无需手动计算归一化位置。
修改后的代码:
import plotly.express as px fig = px.choropleth(merged, locationmode='USA-states', locations='state_po', animation_frame='year', color='R_margin_x', # 自定义红蓝-白双向配色,可根据需求调整颜色深浅 color_continuous_scale=['darkblue', 'lightblue', 'white', 'lightcoral', 'darkred'], color_continuous_midpoint=0, scope='usa') fig.show()
这个方法的优势是简单高效,自动适配每个动画帧的数据范围,始终将0作为配色中点。
方法2:动态更新各帧配色映射
如果需要针对每个选举年份单独校准颜色范围(比如不同年份的差值极值差异极大),可以遍历每个动画帧,计算该年份下0对应的归一化位置,再更新帧的颜色配置。
示例代码:
import plotly.express as px import plotly.graph_objects as go # 创建基础动画图 fig = px.choropleth(merged, locationmode='USA-states', locations='state_po', animation_frame='year', color='R_margin_x', scope='usa') # 遍历每个动画帧,更新颜色刻度 for frame in fig.frames: year = int(frame.name) # 获取当前年份的差值数据 year_data = merged[merged['year'] == year] min_val = year_data['R_margin_x'].min() max_val = year_data['R_margin_x'].max() # 计算0在当前年份数据范围中的归一化位置 zero_pos = (0 - min_val) / (max_val - min_val) # 更新当前帧的配色和数据范围 frame.data[0].update( colorscale=[(0, 'blue'), (zero_pos, 'white'), (1, 'red')], cmin=min_val, cmax=max_val ) # 更新初始帧的颜色配置 initial_year = int(fig.frames[0].name) initial_data = merged[merged['year'] == initial_year] initial_zero_pos = (0 - initial_data['R_margin_x'].min())/(initial_data['R_margin_x'].max()-initial_data['R_margin_x'].min()) fig.update_layout( coloraxis=dict( colorscale=[(0, 'blue'), (initial_zero_pos, 'white'), (1, 'red')], cmin=initial_data['R_margin_x'].min(), cmax=initial_data['R_margin_x'].max() ) ) fig.show()
这个方法能确保每个年份的颜色映射都精准匹配该年份的差值分布,适合数据波动较大的场景。
内容的提问来源于stack exchange,提问作者Felix
相关产品推荐
相关产品推荐

