MATLAB Answers

0

How to plot a position heatmap inside a circle?

Asked by Manal Shakeel on 6 Sep 2019
Latest activity Commented on by Manal Shakeel on 9 Sep 2019
I have x and y coordinates of animal inside a circular arena. I am using hist3 in Matlab to plot a heatmap. I would like to visualize it inside a circle, instead of the default a square with axes (left).
What I would like is this: A circle showing the heatmap, with the white outside. This is just acircle plotted on top and its not aligned properly, because I had trouble passing the centre and axis limits.
I am using hist3 and then imagesc to plot.
Any ideas how to achieve this?

  0 Comments

Sign in to comment.

2 Answers

Answer by Neuropragmatist on 6 Sep 2019
 Accepted Answer

Hi Manal,
I'm always happy to help a fellow animal researcher!
If you know where the center of the arena is in your heatmap this is not so difficult:
img = peaks(64);
xsize = size(img,2);
ysize = size(img,1);
cent = size(img)/2; % if the heatmap is not centered on the center of the arena you will have to adapt this to the real coordinate
radius = xsize/2; % you will have to adapt this for your arena, from your example I assume it fills the image
% generate a circular mask
[cc,rr] = meshgrid(1:xsize, 1:ysize); % x,y indices of all map pixels
circ_mask = sqrt(sum(([rr(:) cc(:)]-cent).^2,2)) <= radius; % cicular mask based on distance from cent
img_masked = img; % duplicate input image
img_masked(~circ_mask(:)) = NaN; % mask it (everything further than radius away from cent is NaN)
% plot the results
figure
subplot(1,2,1)
imagesc(img);
daspect([1 1 1])
subplot(1,2,2)
im = imagesc(img_masked);
set(im,'alphadata',~isnan(img_masked));
daspect([1 1 1])
If you don't know this then when you generate the ratemap using hist3 you should specify the bin edges such that the coordinate of the center of the arena falls in the center bin. If you don't know the coordinate of the arena center then you will have to work that out, otherwise there is no clear way to do what you want (although you could estimate the center as the centroid of the boundary of the animal's trajectory).
Hope this helps,
M.

  7 Comments

Thanks again. Yeah, I am using 2016a. So, this worked when I use your example.
These are the problems I am facing when I try it for my heatmap. So, the centre is 0,0 and I do know the radius.
code:
nBins_x = 40; %specify bins, using 40 here
nBins_y = 40;
Data=[x_walk y_walk]; %x y coordinates of the animal from the data
[counts, bin_centers] = hist3(Data, [nBins_x nBins_y]); %creating histogram
x_bin_centers = bin_centers{1};
y_bin_centers = bin_centers{2};
I=imagesc(x_bin_centers, y_bin_centers, counts) %using thehistogram to plot the heatmap
axis xy tight
axis equal
axis off
colormap(viridis)
pbaspect([1 1 1])
I have the heatmap with this. And I am having thefollowing issue:
1. If I read I directly, (the heatmap) and run your code, this is the error I get:
Cannot convert double value NaN to a handle
Error in plot_arena_heatmap (line 9)
img_masked(~circ_mask(:)) = NaN; % mask it (everything further than radius away from cent is NaN)
alternatively,
2. If I save the heatmap as an image (.png), and then read it, this is what happens:
I get this:
with the following errror:
Error using matlab.graphics.primitive.Image/set
While setting the 'AlphaData' property of 'Image':
Value must be a scalar, vector or array of numeric or logical type
Error in plot_arena_heatmap (line 17)
set(im,'alphadata',~isnan(img_masked));
I think there is a problem passing the axis values when I am reading the image.
If I have the aix labels on in the heatmap, this is what I get:
Any suggestions? I feel like I am missing some important detail.
Hi again Manal,
I think you are passing the output of imagesc to my piece of code when you should be passing the 'counts' output of hist3 instead.
Try running it like this:
figure
nBins_x = 40; %specify bins, using 40 here
nBins_y = 40;
Data=[x_walk y_walk]; %x y coordinates of the animal from the data
% Data = rand(1000,2)*100; % dummy data for testing
[counts, bin_centers] = hist3(Data, [nBins_x nBins_y]); %creating histogram
x_bin_centers = bin_centers{1};
y_bin_centers = bin_centers{2};
I = imagesc(x_bin_centers, y_bin_centers, counts); %using thehistogram to plot the heatmap
axis xy tight
axis equal
axis off
colormap(viridis)
pbaspect([1 1 1])
img = counts;
xsize = size(img,2);
ysize = size(img,1);
cent = size(img)/2; % if the heatmap is not centered on the center of the arena you will have to adapt this to the real coordinate
radius = xsize/2; % you will have to adapt this for your arena, from your example I assume it fills the image
% generate a circular mask
[cc,rr] = meshgrid(1:xsize, 1:ysize); % x,y indices of all map pixels
circ_mask = sqrt((rr - cent(1)).^2 + (cc - cent(2)).^2) <= radius; % cicular mask based on distance from cent
img_masked = img; % duplicate input image
img_masked(~circ_mask(:)) = NaN; % mask it (everything further than radius away from cent is NaN)
% plot the results
figure
subplot(1,2,1)
imagesc(img);
daspect([1 1 1])
subplot(1,2,2)
im = imagesc(img_masked);
set(im,'alphadata',~isnan(img_masked));
daspect([1 1 1])
Hope this helps,
M.
yes, it does. Thanks so much for your help and patience.

Sign in to comment.


Answer by Bruno Luong
on 9 Sep 2019
Edited by Bruno Luong
on 9 Sep 2019

Hide the ouside with a patch
close all
im=peaks; % your heatmap
imagesc(im)
ax = gca;
xl = xlim(ax);
yl = ylim(ax);
% build the patch
x = xl([1 2 2 1 1]);
y = xl([1 1 2 2 1]);
theta = pi+linspace(0,-2*pi).';
% center coordinates and radius of the circle
xc = mean(xl);
yc = mean(yl);
r = diff(xl)*0.3/2;
% rectangle + circle
x = [x(:); xc+r*cos(theta)];
y = [y(:); yc+r*sin(theta)];
% plot on top of the image
hold on
patch('XData',x,'YData',y,'EdgeColor','none','FaceColor','w');
axis equal

  3 Comments

This is a cool way to do it. The benefit of my approach is that statistics can be gathered from the heatmap after masking (std, mean, median etc) and the logical mask can be used to cut other maps of the same size.
M.
Yes, it's purely graphical.
The boundary is clean and not have pixel stair artefact.
zoom.png
This is an elegant solution to the problem. Thanks.

Sign in to comment.