Home > front end >  Adjust Heatmap Bar Matplotlib/Seaborn
Adjust Heatmap Bar Matplotlib/Seaborn

Time:02-06

I want to plot the p-value in a heatmap. I am thus interested in the 1%, 5% and 10% steps. My goal is to plot 3 colors for the before mentioned steps and number that are greater than 0.1 are colored in white.

This is what I have come up with so far: enter image description here

Is there a way to have a completely custom legend/bar at the bottom divided into 4 equally large fields of the 3 blue colors and white:

enter image description here

My code:

Granger2.columns = Granger_colnames
Granger2.index = Granger_rownames
cbar_ticks = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]

fig, ax = plt.subplots(figsize=(6,25)) 
sns.heatmap(Granger2, cmap=rvb, cbar=True, ax=ax,linewidths=.5,vmin=0,cbar_kws={"orientation": "horizontal", "pad":0.01,"ticks": cbar_ticks})
ax.xaxis.tick_top() # x axis on top
ax.xaxis.set_label_position('top')

#Remove ticks
ax.tick_params(axis='both', which='both', length=0)

# Drawing the frame
ax.axhline(y = 0, color='k',linewidth = 1)
ax.axhline(y = Granger2.shape[0], color = 'k',linewidth = 1)  
ax.axvline(x = 0, color = 'k', linewidth = 1)
ax.axvline(x = Granger2.shape[1], color = 'k', linewidth = 1)

cbar = ax.collections[0].colorbar
cbar.ax.axhline(y = 0, color='k',linewidth = 1)
cbar.ax.axhline(y = 1, color = 'k',linewidth = 1)  
cbar.ax.axvline(x = 0, color = 'k', linewidth = 1)
cbar.ax.axvline(x = 1, color = 'k', linewidth = 1)
cbar.ax.tick_params(axis='both', which='both', length=0)
plt.show()

CodePudding user response:

You could use a ListedColormap for the colors, and a BoundaryNorm to set custom boundaries:

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, BoundaryNorm
import numpy as np

bounds = [0, .01, .05, .10, 1]
norm = BoundaryNorm(bounds, ncolors=len(bounds) - 1)
cmap = ListedColormap(['#084a91', '#4a98c9', '#b7d4ea', 'white'])
fig, ax = plt.subplots(figsize=(6, 7))
sns.heatmap(np.random.rand(20, 20), cmap=cmap, norm=norm, cbar=True,
            linewidths=.5, linecolor='lightgrey', clip_on=False,
            cbar_kws={"orientation": "horizontal", "pad": .01}, ax=ax)
ax.xaxis.tick_top()
ax.tick_params(axis="both", length=0)  # hide ticks
for spine in fig.axes[-1].spines.values():
    spine.set(visible=True, lw=.5, edgecolor="grey")  # show outline
plt.tight_layout()
plt.show()

sns.heatmap with custom color boundaries

CodePudding user response:

Step 1:

Transform the Granger2 and redefine it with its range of values using the between function of pandas:

for col in Granger_colnames:
    Granger2.loc[Granger2[col].between(0,0.01), col] = 100
    Granger2.loc[Granger2[col].between(0.01,0.05), col] = 200
    Granger2.loc[Granger2[col].between(0.05,0.1), col] = 300
    Granger2.loc[Granger2[col].between(0.1,1), col] = 400

I pick {100,200,300,400} but you can pick other values.

Step 2:

Apply a new colorscheme to colorbar based on {100,200,300,400}, include this definition in cmap.

Step 3:

Relabel the colorbar with cbar.set_ticklabels(['0.00', '0.01', '0.05', '0.1', '1.00']).

Example:

Then the collowing code with application to a random matrix should work:

# Granger2.columns = Granger_colnames = 
# Granger2.index = Granger_rownames
import pandas as pd
from random import choice
from string import ascii_lowercase, digits
import seaborn as sns

chars = ascii_lowercase   digits
Granger_rownames = [''.join(choice(chars) for _ in range(3)) for _ in range(10)]
Granger_colnames = [''.join(choice(chars) for _ in range(3)) for _ in range(10)]

cbar_ticks = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]

Granger2 = np.random.rand(10, 10)
Granger2 = pd.DataFrame(Granger2, index = Granger_rownames, columns = Granger_colnames) 


#create a mask for Granger2 and change it to {100,200,300,400}
for col in Granger_colnames:
    Granger2.loc[Granger2[col].between(0,0.01), col] = 100
    Granger2.loc[Granger2[col].between(0.01,0.05), col] = 200
    Granger2.loc[Granger2[col].between(0.05,0.1), col] = 300
    Granger2.loc[Granger2[col].between(0.1,1), col] = 400


dataFrame = Granger2
myColors = ((15/256,82/256,186/256, 1), (101/256,147/256,245/256, 1), (220/256, 230/256, 250/256, 1), (1, 1, 1, 1))
cmap = LinearSegmentedColormap.from_list('Custom', myColors, len(myColors))

fig, ax = plt.subplots(figsize=(6,6)) 
ax = sns.heatmap(dataFrame, cmap=cmap, linewidths=1, linecolor='black', cbar_kws={"orientation": "horizontal", "pad":0.01,"ticks": cbar_ticks})
ax.xaxis.tick_top() # x axis on top
ax.xaxis.set_label_position('top')
# Manually specify colorbar and change the label
cbar = ax.collections[0].colorbar
cbar.set_ticks([100, 175, 250, 325, 400])
cbar.set_ticklabels(['0.00', '0.01', '0.05', '0.1', '1.00'])

ax.axhline(y=0, color='k',linewidth=1)
ax.axhline(y=dataFrame.shape[1], color='k',linewidth=1)
ax.axvline(x=0, color='k',linewidth=1)
ax.axvline(x=dataFrame.shape[0], color='k',linewidth=1)
plt.show()

enter image description here

  •  Tags:  
  • Related