I want to make a heatmap using seaborn. I have a 1920x1080 2D array that contains saliency values of each pixel of an image from 0-1 (0=lowest saliency-blue color, 1=highest saliency-red color). I have divided my image into smaller grids of 80x90 pixels. I am getting the image below:
So far so good. What I want to do next is to create a seaborn heatmap, so that each grid is averaged and represented by only one color (with blue grids representing areas of low saliency and warmer grids representing areas of high saliency), like below:
However, using this code:
import numpy as np
plt.figure(figsize= (16,9))
xticklabels=range(0,1920,80)
yticklabels=range(0,1080,90)
xticks[80,160,240,320,400,480,560,640,720,800,880,960,1040,1120,1200,1280,1360,1440,1520,1600,1680,1760,1840,1920]
yticks=[90,180,270,360,450,540,630,720,810,900,990,1080]
normalized_saliency_map=np.random.random((1080,1920))
ax=sns.heatmap(normalized_saliency_map,
cmap='jet',
linewidth=0.5,
xticklabels = xticklabels,
yticklabels = yticklabels)
ax.set_xticks(xticks)
ax.set_yticks(yticks)
plt.title(f'Image: {i}')
plt.show()
I am getting this empty plot:
If I comment out ax.set_xticks(xticks)
and ax.set_yticks(yticks)
, I am getting this:
What am I missing here?
CodePudding user response:
Main Array
- Remove
linewidth
- Add
set_xticklabels
andset_yticklabels
# test data
np.random.seed(365)
data = np.random.random((1080,1920))
ax = sns.heatmap(data, cmap='jet')
ax.set_xticks(xticks) # this is only the tick location, not the label
ax.set_xticklabels(xticks) # this adds the labels, after setting the ticks
ax.set_yticks(yticks)
ax.set_yticklabels(yticks)
ax.invert_yaxis() # use if desired to swap the direction of the y-axis values
ax.grid(color='k')
plt.show()
Divide the Array
- I used the function in this
blockshaped
- Here's the function from the other answer for reshapeding the array
def blockshaped(arr, nrows, ncols): """ Return an array of shape (n, nrows, ncols) where n * nrows * ncols = arr.size If arr is a 2D array, the returned array should look like n subblocks with each subblock preserving the "physical" layout of arr. """ h, w = arr.shape assert h % nrows == 0, f"{h} rows is not evenly divisible by {nrows}" assert w % ncols == 0, f"{w} cols is not evenly divisible by {ncols}" return (arr.reshape(h//nrows, nrows, -1, ncols) .swapaxes(1,2) .reshape(-1, nrows, ncols))