如何基于单列将数据框着色为在整行中具有相同颜色的条件热图

How to color a dataframe to a conditional heatmap with same color across whole row based on a single column

所以我有一个看起来像这样的数据框:

Target, Achieved, Goal, Remaining
10, 5, 50, 5
4, 5, 125, 0
3, 3, 100, 0
8, 2, 25, 6

我想根据颜色显示带有可见信息的数据框,在此条件下:

  1. 如果实现了目标,我只想让行显示为绿色,而不管实际超出目标的程度如何。所以整个第二行和第三行将是相同的绿色
  2. 如果没有达到目标,我想根据热图给它们上色。所以在这里我希望第 4 行比第 1 行更暗(可以说是红色),因为我在该行的目标上遗漏了更多内容。

对于单一颜色,以下功能完美运行:感谢回答

def highlight_col(x):
    #copy df to new - original data are not changed
    df = x.copy()
    #set by condition
    mask = df['Goal Completion (%)'] >= 100
    df.loc[mask, :] = 'background-color: lightgreen'
    df.loc[~mask,:] = 'background-color: pink'
    return df      

对于不排除目标完成条件的简单热图,可以通过:

df.style.background_gradient(cmap='Reds')

但是它:

  1. 包括整​​个数据帧
  2. 每列分别着色
  3. 无法排除已实现目标的行
  4. 无法在我上面的函数中使用(尝试在最后一行使用:df.loc[~mask,:] = 'background_gradient: Reds',但也没有用。

P.S。我的 Dataframe 不是很大,所以我更喜欢 table 从我可以 select 行的地方着色,而不是拥有一个全新的可视化。非常欢迎任何改善情况的建议!

示例输出:

您可以将 cmap 应用于数据帧的特定子集

df.style.background_gradient('Reds', subset=pd.IndexSlice[df.Goal < 100, ])

输出

您可以尝试通过 Goal 中的值提取颜色 cmap:

def hightlight_col(d, refcol=None, cmap='Reds'):
    min_goal, max_goal = d[refcol].agg(['min','max'])
    goals = d[refcol].sub(min_goal)/(max_goal-min_goal)
    cmap=mpl.cm.get_cmap(cmap)
    
    return pd.DataFrame([[f'background-color: {mpl.colors.to_hex(cmap(goal))}']*d.shape[1]
                   for goal in goals
                 ], index=d.index, columns=d.columns)
    
df.style.apply(hightlight_col, refcol='Goal', 
               cmap='coolwarm', axis=None)

输出:

也许您正在寻找这样的东西(使用@QuangHoang 方法):

import pandas as pd
import numpy as np
import matplotlib as mpl

df = pd.read_clipboard(sep=',\s+')

cmap = mpl.cm.get_cmap('RdYlGn')
norm = mpl.colors.Normalize(df['Goal'].min(), 100.)

def colorRow(s):
    return [f'background-color: {mpl.colors.to_hex(cmap(norm(s["Goal"])))}' for _ in s]


df.style.apply(colorRow, axis=1)

输出: