0

I'm wondering if someone can help me with the following. I have some data in the form of x- and y-coordinates, and I want to make a heatmap i.e. time spent looking at the specific coordinates. It is quite a lot of data, so I'm linking to an example of it here in my gdrive (here).

Using Jurgy's answer from this post (here), I've made the following code:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from scipy.ndimage.filters import gaussian_filter

# get the data
df = pd.read_csv(r'C:\Users\L\Desktop\df.csv')
x, y  = df['x'], df['y']

# remove zero values because these are not supposed to be ther.
x = x[x > 0]
y = y[y > 0]

# function from linked SO question
# I edited the bins argument
def myplot(x, y, s, bins=(1280, 768)):
    heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins)
    heatmap = gaussian_filter(heatmap, sigma=s)

    '''i have tried editing this to be:
    extent = [0, 1280, 0, 768]#, but this just seems to 
    rescale everything, fitting it to within the space
    and it no longer represents the correct regions/coordinates.'''
    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

    return heatmap.T, extent

sigma = 32
img, extent = myplot(x, y, sigma)

plt.imshow(img, extent=extent, cmap=cm.jet)
#plt.xlim(0, 1280)
#plt.ylim(0, 768)
plt.colorbar()
''' I also tried to define xlims and ylims.
 this positions it correctly, but there
 is a lot of bounding whitespace. The only way 
 I can think to solve that is to append some
 values to the x- and y-coordinates to include
 the limits like:
xlims, ylims = pd.Series([0, 1280]), pd.Series([0, 768])
x, y = x.append(xlims), y.append(ylims)
x.reset_index(inplace=True, drop=True)
y.reset_index(inplace=True, drop=True)
but it also doesn't work...'''

And this gives me the following nice result: enter image description here

I know this seems to be exactly what I want to see in terms of the "shape" of the data. But I have some issues: 1. My data represents a computer monitor screen with resolution 1280x768, so I need the plot to reflect this and I can't seem to get that right - as you can see from the comments in the code. In this way I need the plot to be as large as the following, but obviously without the whitespace: enter image description here

  1. I also wanted the scale to be different (I don't even know what scale this is at the moment). Each row of x- and y-data represent approx ~16.6667 ms (the data acquisition rate), and I want it to be scaled based on the time (ms) in each coordinate. At the moment the colour scale is from 0 to 0.08 and I'm not sure where this is coming from. I would expect the scale to be more like 0 to 2000 or so.
fffrost
  • 1,659
  • 1
  • 21
  • 36
  • It's really hard to follow what exactly is wrong with the result you currently have as well as with the attempts that have been made. – ImportanceOfBeingErnest Apr 12 '18 at 11:47
  • I edited the OP. Basically I want the plot to represent the entire screen (1280*768), as in the second image when I define the xlims and ylims but without the whitespace. I also can't figure out the scaling that resulted - 0 to 0.08. Each row of data represents about 16 ms and I need it scaled as such. For example, the bottom right region where there is higher density means that there was more time spent observing it, but a scale of 0-0.08 is clearly incorrect and I'm not sure how to map the correct times to this scale. I'm not sure how else to explain it. – fffrost Apr 12 '18 at 12:18
  • Have you tried to add `plt.axes().set_aspect('equal')` instead if `xlim` or `ylim`? – marco romelli Apr 12 '18 at 12:40
  • Also I think I would use [seaborn](https://seaborn.pydata.org/generated/seaborn.heatmap.html) for the heatmap. – marco romelli Apr 12 '18 at 12:47
  • @marcoromelli I have tried you suggestion but it doesn't seem to do anything at all. – fffrost Apr 12 '18 at 13:17
  • I tried your code. It works fine for me if I use `plt.imshow(img, cmap='jet'). I get the correct aspect ratio. – marco romelli Apr 12 '18 at 14:14
  • It seems there is no data lower than ~300 or above 1000. So that is missing. Of course you could let the histogram be generated over the whole range of data you're interested in. Or you could colorize the background the same as the lowest colormap color. – ImportanceOfBeingErnest Apr 12 '18 at 15:20
  • @ImportanceOfBeingErnest that's true. I had considered colourising it as you suggest, but I wasn't sure if this was appropriate. I thought a better way might be to expand the matrix to include zeros where that missing data would be, but I haven't figured out how to achieve this. Also the gaussian blurring is what causes the issue for the scaling. I was thinking that I could generate a second plot without the gaussian blur, and then use that plot's colour bar which would then correct the scaling but it doesn't seem like a clean solution. – fffrost Apr 12 '18 at 15:31

0 Answers0