How to make a heatmap with density of points

Hello!
I have two vectors ( x_vector and y_vector) which correspond with the different points obtained on my simulation. The point is that I want to make a kind of heatmap with the density of the repetition of those points. I have tried with different functions such as imagesc or histogram2, but I didn't get to achieve what I wanted.
Thank you.

 Risposta accettata

jonas
jonas il 22 Ago 2018
Modificato: jonas il 22 Ago 2018

14 Commenti

Thank you, but in this thread they are using matrix instead of vectors (as in my case, which are vectors of 1xN)
Did you try it? The syntax X(:) makes the matrix into a vector, so it works for both.
Okey, I tried it and it works. Thank you so much. One more thing, when i plot the histogram..I want all the figure to be coloured, but there are some margins that don't appear that way. Any idea on how to fix this?
Great!
axis tight
should fix it. If not, please upload an image describing the issue.
I'll explain with more detail the full issue.
I'm using an eyetracker to get x and y coordinates of where I'm looking at. My goal is to create a heatmap with those coordinates, which I have stored in two vectors (files attached).
My screen is 1920x1080...so I want the axis to have that length fixed. This is the code I'm using to create the heatmap:
figure()
nbins = [60 60];
hist3([x_vector(:), y_vector(:)], nbins, 'CdataMode','auto', 'EdgeColor', 'interp')
axis([0 1920 0 1080]);
xticks([0:240:1920])
yticks([0:135:1080])
set(gca, 'ydir', 'reverse', 'xaxislocation', 'top')
And this is the result I got:
The point is that I would like that space at the bottom of the figure to be filled as well.
Thank you for your help!
jonas
jonas il 24 Ago 2018
Modificato: jonas il 24 Ago 2018
Instead of bin amount, you can define the grid, using edges argument
hist3([x_vector(:), y_vector(:)],'CdataMode','auto', 'EdgeColor', 'interp','edges',{linspace(0,1920,nbins(1)) linspace(0,1080,nbins(2))})
I wrote it so that your code still works when you replace the hist3 line. The edges argument is a 1x2 cell array.
Don't forget to try some alternative surface plots. In my opinion they are more visually appealing. Here's a surf with the magma colormap
You just need to specify the output from hist3 and then use that as input to surf, contour, mesh etc...
[N,C]=hist3(...)
surf(C{1},C{2},N)
Thank you so much, I'll take a look at those colormaps you linked. But...when I use countourf with the outputs of the hist3 you suggested, there's a new margin unfilled:
jonas
jonas il 24 Ago 2018
Modificato: jonas il 24 Ago 2018
You are correct! The surface also extends beyond the axes limits. I havn't noticed this before but it becomes abundantly clear when the bin count is low. This is probably because the output X/Y-data from hist refer to the bin centers, so everything is shifted half a bin width/height to the right/bottom. Add these two lines after [C,N]=hist3(...) to adjust for this:
C{1}=C{1}-min(C{1});
C{2}=C{2}-min(C{2});
Yes, that lines fixed the problem, but I have represented the points of the vectors over the heatmap...and I think it is not very accurate:
jonas
jonas il 24 Ago 2018
Modificato: jonas il 24 Ago 2018
The hist3 plot looks OK but the surf has been rotated. Try transposing N
surf(C{1},C{2},N')
Sorry for the many bugs :)
This looks quite neat:
contourf(C{1},C{2},N','levelstep',1,'edgecolor','none')
colormap(magma)
Hi Jonas! Thank you so much for your help. Everything works fine now. I have a little doubt about how this lines corrected the problem I had:
C{1}=C{1}-min(C{1});
C{2}=C{2}-min(C{2});
I understand that it is to correct the shifting, what I don't understand is why we have to subtract min(C{1})
C{1} describe the x-coordinates and C{2} describe the y-coordinates. I drew a picture to show you the rationale, using a much courser grid so that the offset becomes significantly larger. In short, we move the entire grid so that [min(C{1}) ; min(C{2})] is located at the origin.
Ahhhhh okey okey, I didn't know that min(C{2}) meant C{2}(1). I supposed that it would return the minimum value of that array.
Thank you!!
jonas
jonas il 30 Ago 2018
Modificato: jonas il 30 Ago 2018
Well you were not incorrect, min(C{2}) does not always equal C{2}(1). However, in this specific case C{2}(1) is the minimum value of C{2}. It works both ways.
Sorry for the confusing code ;)

Accedi per commentare.

Più risposte (1)

Walter Roberson
Walter Roberson il 22 Ago 2018

2 Commenti

Great answer to this question! I'd like to ask a follow up question. Can a number be extracted to indicate the extent of density in a data set? i.e. how focused is a heatmap?
If you use Malcolm's contribution, then his dataDensity() function calculates those numbers.

Accedi per commentare.

Categorie

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by