如何为Holoviews热力图的每一行设置独立色阶?
实现Holoviews热力图每行独立色阶条件格式
需求说明
我希望为热力图中的每一行设置不同的条件格式——即颜色保持一致,但色阶需对每行独立应用。以Holoviews的美国失业率示例代码为例:
import pandas as pd import holoviews as hv from bokeh.sampledata.unemployment1948 import data hv.extension('bokeh') data = pd.melt(data.drop('Annual', 1), id_vars='Year', var_name='Month', value_name='Unemployment') heatmap = hv.HeatMap(data, label="US Unemployment (1948 - 2013)") colors = ["#75968f", "#a5bab7", "#c9d9d3", "#e2e2e2", "#dfccce", "#ddb7b1", "#cc7878", "#933b41", "#550b1d"] heatmap.opts( opts.HeatMap(width=900, height=400, xrotation=45, xaxis='top', labelled=[], tools=['hover'], cmap=colors))
目标是让y轴上每个月份行的色阶独立计算,比如十二月的数值不会影响一月行的颜色(正常效果是全局应用色阶,预期效果为每行独立应用色阶)。
解决方案
核心思路是对每行(按Month分组)的数值单独做0-1归一化,再用归一化后的值映射颜色,同时保留原数值用于hover提示。修改后的代码如下:
import pandas as pd import holoviews as hv from bokeh.sampledata.unemployment1948 import data hv.extension('bokeh') # 数据预处理 data = pd.melt(data.drop('Annual', 1), id_vars='Year', var_name='Month', value_name='Unemployment') # 按Month分组,对每组Unemployment做0-1归一化 def normalize_series(s): return (s - s.min()) / (s.max() - s.min()) data['Normed_Unemployment'] = data.groupby('Month')['Unemployment'].transform(normalize_series) # 创建热力图,用归一化值映射颜色,hover显示原数值 heatmap = hv.HeatMap(data, kdims=['Year', 'Month'], vdims=['Normed_Unemployment', 'Unemployment'], label="US Unemployment (1948 - 2013)") colors = ["#75968f", "#a5bab7", "#c9d9d3", "#e2e2e2", "#dfccce", "#ddb7b1", "#cc7878", "#933b41", "#550b1d"] heatmap.opts( opts.HeatMap(width=900, height=400, xrotation=45, xaxis='top', labelled=[], tools=['hover'], cmap=colors, hover_opts={'tooltips': [('Year', '@Year'), ('Month', '@Month'), ('Unemployment', '@Unemployment')]}))
关键说明
- 分组归一化:通过
groupby('Month').transform实现每行独立的数值缩放,确保每个月份的最大值对应颜色映射的最深色,最小值对应最浅色,互不干扰。 - hover优化:热力图的颜色由归一化值驱动,但hover提示显示原始失业率数值,避免用户混淆。
- 颜色一致性:保留原有的颜色列表
colors,确保所有行使用同一套颜色体系,仅色阶计算范围独立。
内容的提问来源于stack exchange,提问作者Vasconni
相关产品推荐
相关产品推荐

