Highlight custom color for the Mean Value data cell of every column in heatmap using pandas df

Viewed 542

I am trying to Highlight the Mean Value cell or Lowest value cell of Mean value in pandas heatmap but it always giving failure result for me. I wants to Highlight the cell of Exact mean value in the heatmap if exact value not available means need to highlight lowest value for the meanvalue.

For Ex: Meanvalue is 17.522 but not available in df means need to highlight 15.499 (refer

Here I have Shared Screen shots of What I tried and What is my Expectation for your ref.

Genius Always Welcome..! Thanks in Advance.

Each Column Mean Values are,

array([17.60950419, 33.73034387, 46.63401871, 56.27580645, 52.62956452,
       63.70669355, 71.75735484, 67.788     , 83.62327419, 75.41342   ])

I have tried following code to Highlight the single cell

df_Mean=np.array(df.mean())

fig, ax = plt.subplots(figsize=(18,8))

cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#f9f9f9","#B6DBF2","#327AD9","#3068D9"])
color = ["#f9f9f9",'#3068D9',"#f9f9f9","#f9f9f9","#B6DBF2","#327AD9","#3068D9"]

ax = sns.heatmap(df, annot=True, fmt=".5g", linewidths=.02, 
                 cmap=cmap, vmin=0, vmax=300,cbar_kws={'label': 'Si.No'}, 
                linecolor='#CBDBD7',
                ax = ax,
                xticklabels=1, yticklabels=1,
                )

ax = sns.heatmap(df.round(),mask=(df > df_Mean),
             vmin=10, vmax=80, cmap=color, cbar=False)

ax.invert_yaxis()
ax.yaxis.set_label_position("right")
ax.yaxis.tick_right()

ax.set_xticklabels(
    ax.get_xticklabels(), color = 'darkgreen',
    horizontalalignment='center');

ax.set_yticklabels(
    ax.get_yticklabels(), color = 'darkblue',
    horizontalalignment='right',
    size = 10,);

ax.xaxis.set_tick_params(pad=10)
ax.yaxis.set_tick_params(pad=20)  

plt.xlabel('Month', color = 'Maroon', size= 15)
plt.title('Testing_HeatMap', color = 'darkgreen', size = 20)
plt.show()

I am getting this Output, I am getting this Output

Expected Output is: enter image description here

1 Answers

Here I've demonstrated a solution on some random data (but it should illustrate the method for your set up).

For each column I find the row number of the value closest to the column mean, which is less than or equal to the column mean:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import pandas as pd
import seaborn as sns

# Generate some random data (25 rows, 3 columns)
df = pd.DataFrame(np.random.rand(25, 3))

# Compute the mean of each column
df_mean = df.mean()

# Find the difference between each value and the column mean
diff = df - df.mean()

# We are only interested in values less than or equal to the mean
mask = diff <= 0

# The row numbers of the closest values to the column mean
# which are less than or equal to the column mean
highlight_row = np.nanargmin(np.array(df[mask]), axis=0)

Once you've got these row numbers the only remaining thing to do is to plot them. One way to do this would be using the Rectangle patch (although there are undoubtedly other ways to do this):

# Plotting
fig, ax = plt.subplots()
ax = sns.heatmap(df, ax=ax)

# Loop over the columns
for col in range(df.shape[1]):
    # Add a rectangle which highlights our cell of interest
    ax.add_patch(Rectangle((col, highlight_row[col]), 1, 1))
Related