You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Plotly热力图(px.imshow)设置条件配色方案?

实现px.imshow热力图负收益红色、正收益绿色的美观配色方案

问题描述

使用Plotly Express的px.imshow生成收益热力图,现有数据处理及绘图代码如下:

returns = returns.pivot('year', 'month', 'tradegain').fillna(0)
returns = returns[['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']]
returns['Total returns'] = dayret.groupby(dayret.index.year).tradegain.sum().values
returns = round(returns,2)
fig = px.imshow(returns,text_auto=True,aspect='auto',title=title,color_continuous_scale= px.colors.sequential.BuGn_r)

希望实现负收益单元格显示红色系,0及正收益显示绿色系的视觉效果,尝试过自定义色阶但未得到理想结果,需要美观的实现方法。

解决方案

核心是基于数据的绝对数值范围,以0为分界点精准定义颜色映射,避免使用相对比例导致的分界偏移。以下是两种可行方案:

方案1:带渐变的美观配色(推荐)

通过计算0值在数据极值区间内的相对位置,设置红色系与绿色系的衔接点,同时保留渐变过渡提升视觉舒适度:

import plotly.express as px

# 保留原有数据处理代码
returns = returns.pivot('year', 'month', 'tradegain').fillna(0)
returns = returns[['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']]
returns['Total returns'] = dayret.groupby(dayret.index.year).tradegain.sum().values
returns = round(returns,2)

# 获取数据的全局极值,固定颜色映射范围
min_val = returns.min().min()
max_val = returns.max().max()

# 计算0值在[min_val, max_val]区间内的相对位置
zero_pos = (0 - min_val) / (max_val - min_val)

# 自定义色阶:负收益从亮红到深红,0及以上从亮绿到深绿
color_scale = [
    [0.0, '#ff6666'],       # 最小负收益对应亮红色
    [zero_pos, '#cc2222'],  # 0值位置对应深红(红色系终点)
    [zero_pos, '#22cc22'],  # 0值位置对应亮绿(绿色系起点)
    [1.0, '#118811']        # 最大正收益对应深绿色
]

fig = px.imshow(
    returns,
    text_auto=True,
    aspect='auto',
    title=title,
    color_continuous_scale=color_scale,
    cmin=min_val,  # 固定颜色范围最小值,避免数据变化导致分界偏移
    cmax=max_val   # 固定颜色范围最大值
)

# 可选:优化颜色条显示,标注关键节点
fig.update_layout(
    coloraxis_colorbar=dict(
        tickvals=[min_val, 0, max_val],
        ticktext=['最低负收益', '0', '最高正收益']
    )
)

fig.show()

方案2:纯色块无渐变

如果需要明确的红/绿分界,无渐变效果,可使用以下色阶定义:

# 计算0值相对位置(同方案1)
min_val = returns.min().min()
max_val = returns.max().max()
zero_pos = (0 - min_val) / (max_val - min_val)

# 纯红/绿分界的色阶
color_scale = [
    [0.0, 'red'],
    [zero_pos, 'red'],
    [zero_pos, 'green'],
    [1.0, 'green']
]

# 后续绘图代码同方案1
fig = px.imshow(returns, text_auto=True, aspect='auto', title=title, color_continuous_scale=color_scale, cmin=min_val, cmax=max_val)
fig.show()

为什么之前的尝试无效?

之前的自定义色阶使用了相对比例(如0.0、0.5),该比例是基于数据的最小值和最大值自动计算的相对位置,而非绝对的0值。当数据的极值范围不对称时(比如正收益远大于负收益的绝对值),0值不会落在0.5的位置,导致颜色分界错误。通过计算0值的绝对相对位置,才能确保颜色映射精准对应收益正负。

内容的提问来源于stack exchange,提问作者Anirudh B M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 07:01:02