3

I try to make a program for plotting a heat map based on the clicks from the participants. There are two bodies with increase and decrease emotions.

I want to show the intensity of clicks on the left body with blue color (more intense blue = more number of clicks) and right body with red color.

The problem is that I need to show it in one body and also with the background image over which I see the heat map.

x=blue[:,1]
y=blue[:,2]
ax = plt.gca()

heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
plt.imshow(heatmap.T, extent=extent, origin='lower')
ax = plt.gca()
ax.invert_yaxis()

plt.show()

x1=red[:,1]
y1=red[:,2]
ax = plt.gca()

heatmap, xedges, yedges = np.histogram2d(x1, y1, bins=50)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

plt.clf()
plt.imshow(heatmap.T, extent=extent, origin='lower')
ax = plt.gca()
ax.invert_yaxis()

plt.show()
plt.imshow(image)

imageFile = cbook.get_sample_data('C:\\Users\\Admin\\Desktop\\pythonpca\\result.png')
image = plt.imread(imageFile)
plt.plot(all_samples[0:240,0],all_samples[0:240,1], 'o', markersize=3, color='blue', alpha=0.5, label='increase')
plt.imshow(image)

By this I get a heat map for the left body clicks, a heat map for right body clicks and a picture of the left and right bodies. I want them all in the same picture, with blue and red hotspots. I am attaching the pictures I get with this.

2 bodies picture (I have plotted blue points on it, but I do not need the points):

2 bodies picture ( I have plotted blue points on it, but I do not need the points

The heat maps from the left and right bodies:

the heat maps from the left and right bodies

Please let me know if I should add more info.

user812786
  • 4,302
  • 5
  • 38
  • 50
  • maybe you should take a look at `seaborn` it's a nice wrapper for matplotlib, and also have some nice heatmaps – Marvin Taschenberger Aug 15 '17 at 17:29
  • if you can express back and front by e.g. positive and negative numbers you can use a diverging color map https://matplotlib.org/users/plotting/colormaps/lightness_03.png https://matplotlib.org/users/colormaps.html#diverging I guess your approach is fine so far, you just have to translate the coordinates of the right plot to the left one, e.g. by subtracting the offset from the x values. – Joe Aug 15 '17 at 18:37

1 Answers1

4

You could use two different colors to represent left vs right-body clicks, and use the opacity (alpha channel) to represent the density of clicks within a given region. One way to do this would be to create a custom LinearSegmentedColormap that varies in the alpha channel:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import colors

# Some fake data
nbins = (50, 50)
ranges = ((-2, 2), (-2, 2))
lx, ly = np.random.randn(2, 10000) * 0.5 + 1
rx, ry = np.random.randn(2, 10000) * 0.75 - 1

# Compute 2D histograms
left_density = np.histogram2d(lx, ly, bins=nbins, range=ranges, normed=True)[0]
right_density = np.histogram2d(rx, ry, bins=nbins, range=ranges, normed=True)[0]

# Make some custom colormaps that vary in the alpha channel.
trans2blue = colors.LinearSegmentedColormap.from_list(
    name='Trans2Blue', colors=[(0., 0., 1., 0.), (0., 0., 1., 1.)])
trans2red = colors.LinearSegmentedColormap.from_list(
    name='Trans2Red', colors=[(1., 0., 0., 0.), (1., 0., 0., 1.)])

# `imshow` the histograms using the custom colormaps.
fig, ax = plt.subplots(1, 1)
left_im = ax.imshow(left_density, cmap=trans2blue)
right_im = ax.imshow(right_density, cmap=trans2red)

right_cb = fig.colorbar(right_im)
right_cb.set_label('Right click density')
left_cb = fig.colorbar(left_im)
left_cb.set_label('Left click density')

# Workaround for https://stackoverflow.com/q/15003353/1461210
left_cb.solids.set_edgecolor("face")
right_cb.solids.set_edgecolor("face")

fig.tight_layout()

enter image description here

Another way to achieve the same effect would be to construct two (rows, cols, 4) arrays of RGBA pixel values where the alpha channel contains your density values, and RGB contains your desired color, then imshow these on top of one another. Using a custom colormap has a few advantages though - the colormap range gets scaled automatically, and it's fairly easy to add colorbars.

ali_m
  • 71,714
  • 23
  • 223
  • 298
  • Thank you so much ! – Arun Subraminion Aug 17 '17 at 15:06
  • @ArunSubraminion Glad to help. Don't forget to accept the answer if it addresses your question. – ali_m Aug 17 '17 at 19:43
  • can I ask how to add a background image to this ? Also, if I would like to add PCA to this program based on where the participants have clicked so that I could differentiate different test cases, how can I do it ? I mean I would like to find for which emotion the area where people clicked was strange. – Arun Subraminion Aug 28 '17 at 14:21
  • Since the overlaid histogram images are semi-transparent, you could just `imshow` your background image in the same set of axes before `imshow`ing your two heatmap arrays on top. How to perform PCA is really a totally separate question, so I'm not going to try to answer it in the comments here. Before you open a new question, try searching on StackOverflow first, since there are already lots of existing answers explaining various ways to perform PCA in Python, e.g. [here](https://stackoverflow.com/q/1730600/1461210) and [here](https://stackoverflow.com/q/13224362/1461210). – ali_m Aug 28 '17 at 17:55