heatmap_blog-Copy1

Temperature Gradient Matrix

with annotation on the plot

In [1]:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import Image

This is part of a project I was working on.
For this I need to find the temperature field on the ship helo-deck region for many cases and to ensure, the temperature over there has not exceeded the acceptable levels.

There is a research paper for this with a plot showing Temperature Gradient Matrix.

In [2]:
Image(filename='tgm.png')
Out[2]:

Now I have to digitize this plot and put which cases lie at these levels.
This is a simple task, can do with a heat map filling the cell grid with the required color.
We have three colors here, red, green and amber.
In Seaborn, we can customize the color palette. We have three colors here, red, green and amber.
These colors hex value can be found by uploading the image at https://imagecolorpicker.com/ and picking the color.

Customized Color palette

In [3]:
Gr_Ye_Rd = ["#00AF50", "#FFC000","#FE0000"]
sns.palplot(sns.color_palette(Gr_Ye_Rd))
plt.show()

Make a zero array of size 8 x 5
and give the array values as 0 for green, 0.5 for amber and 1 for red

Array for plot values

In [4]:
data = np.zeros((8,5))
In [5]:
data_mod = data.copy()

data_mod[2:,1:] = 0.5

data_mod[5:,3:] = 1

data_mod[3:5,4]= 1
In [6]:
# Now the modified array looks like
data_mod
Out[6]:
array([[ 0. ,  0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0.5,  0.5,  0.5,  0.5],
       [ 0. ,  0.5,  0.5,  0.5,  1. ],
       [ 0. ,  0.5,  0.5,  0.5,  1. ],
       [ 0. ,  0.5,  0.5,  1. ,  1. ],
       [ 0. ,  0.5,  0.5,  1. ,  1. ],
       [ 0. ,  0.5,  0.5,  1. ,  1. ]])

For annotation on the plot

We annotate this plot with text, to say which particular case is falling on which grid cell of this matrix plot.
For this, we will make an array of strings.

In [7]:
labels = np.array([['' for i in range(5)] for j in range(8)],dtype='U15')
In [8]:
labels[5,1] = 'cases_1'
labels[6,1] = 'cases_2'
labels[5,2] = 'cases_3'
labels[6,2] = 'cases_4'
In [9]:
labels
Out[9]:
array([['', '', '', '', ''],
       ['', '', '', '', ''],
       ['', '', '', '', ''],
       ['', '', '', '', ''],
       ['', '', '', '', ''],
       ['', 'cases_1', 'cases_3', '', ''],
       ['', 'cases_2', 'cases_4', '', ''],
       ['', '', '', '', '']],
      dtype='<U15')

Plotting

In [10]:
# This is size of the figure
from matplotlib import rcParams
rcParams['figure.figsize'] = 10,5
In [11]:
import numpy as np
import seaborn as sns; sns.set()
ax = sns.heatmap(data_mod, cmap=sns.color_palette(Gr_Ye_Rd),linewidths=2, linecolor='black',cbar = False, annot=labels,fmt='',annot_kws={"size": 16})
plt.yticks(rotation=0)


# These are the labels we want to use instead of automated numerics 

ax.set_xticklabels(['0<=2','>2','>10','>30','>40'], fontsize=12)
ax.set_yticklabels(['<50', '<40', '<30', '<25', '<20', '<15', '<10', '<5'], fontsize=12)


# matplotlib.rcParams.update({'font.size': 22})
plt.xlabel('Temperature rise above ambient',fontsize=17)
plt.ylabel('Height above helo-deck (m)',fontsize=17)
plt.title('Tempearture Gradient Matrix',fontsize=20)
# plt.savefig('temp_matrix.png')
cbar_ax=None
plt.show()

We can see the seaborn plot properties

In [12]:
sns.axes_style()
Out[12]:
{'axes.axisbelow': True,
 'axes.edgecolor': 'white',
 'axes.facecolor': '#EAEAF2',
 'axes.grid': True,
 'axes.labelcolor': '.15',
 'axes.linewidth': 0.0,
 'figure.facecolor': 'white',
 'font.family': ['sans-serif'],
 'font.sans-serif': ['Arial',
  'DejaVu Sans',
  'Liberation Sans',
  'Bitstream Vera Sans',
  'sans-serif'],
 'grid.color': 'white',
 'grid.linestyle': '-',
 'image.cmap': 'rocket',
 'legend.frameon': False,
 'legend.numpoints': 1,
 'legend.scatterpoints': 1,
 'lines.solid_capstyle': 'round',
 'text.color': '.15',
 'xtick.color': '.15',
 'xtick.direction': 'out',
 'xtick.major.size': 0.0,
 'xtick.minor.size': 0.0,
 'ytick.color': '.15',
 'ytick.direction': 'out',
 'ytick.major.size': 0.0,
 'ytick.minor.size': 0.0}

Below cells are for styling, you can happily ignore them

In [13]:
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))