# plot a 2D circular intensity map

49 views (last 30 days)
Sharon on 30 May 2024
Commented: Adam Danz on 31 May 2024
Dear all,
i would like to plot a 2D map showing below. I have x and y coordinates and z being the intensity showing as in different scale in color.
for the areas without the datapoint, i might need to interpolate the gap.
does anyone know how i can do this?
thanks so much for your help

Adam Danz on 30 May 2024
Edited: Adam Danz on 31 May 2024
This demo assumes you have a vector of x-coordinates, a vector of y-coordinates, and a vector of intensity values.
It uses griddata to interpolate the values and organize the intensity values into a grid.
The interpolated grid values are plotted using pcolor.
N = 5000;
th = 2*pi * rand(N,1);
x = r.*cos(th); % x coordinate
y = r.*sin(th); % y coordinate
intensity = hypot(10-x,10-y); % intensity values
% interpolate in a grid
resolution = 500; % resolution of the interpolation
[Xq,Yq,intensityq] = griddata(x,y,intensity,...
linspace(min(x),max(x),resolution),...
linspace(min(y),max(y),resolution)');
% Plot results, use interpolated face color
p = pcolor(Xq,Yq,intensityq);
p.FaceColor = 'interp';
p.EdgeColor = 'none';
axis equal
colorbar()
grid on
Compare that to the original data
figure()
scatter(x,y,10,intensity,'filled')
axis equal
grid on
colorbar()
##### 3 CommentsShow 1 older commentHide 1 older comment
Adam Danz on 31 May 2024
Edited: Adam Danz on 31 May 2024
If you want to expand the regions to fill the range of data, it will result in a square since the range is the min and max along the x and y axes. One easy way to do that is to change the interpolation method in griddata. Below shows the results for "v4" and "nearest" neighbor interpolation methods. The only change is to specify the method in the 6th argument to griddata.
N = 5000;
th = 2*pi * rand(N,1);
x = r.*cos(th); % x coordinate
y = r.*sin(th); % y coordinate
intensity = hypot(10-x,10-y); % intensity values
% interpolate in a grid
resolution = 500; % resolution of the interpolation
[Xq,Yq,intensityq] = griddata(x,y,intensity,...
linspace(min(x),max(x),resolution),...
linspace(min(y),max(y),resolution)', ...
'v4'); % <------------------------------- SPECIFY METHOD
% Plot results, use interpolated face color
p = pcolor(Xq,Yq,intensityq);
p.FaceColor = 'interp';
p.EdgeColor = 'none';
axis equal
colorbar()
grid on
title('griddata interp method: v4')
figure()
resolution = 500; % resolution of the interpolation
[Xq,Yq,intensityq] = griddata(x,y,intensity,...
linspace(min(x),max(x),resolution),...
linspace(min(y),max(y),resolution)', ...
'nearest'); % <------------------------------- SPECIFY METHOD
% Plot results, use interpolated face color
p = pcolor(Xq,Yq,intensityq);
p.FaceColor = 'interp';
p.EdgeColor = 'none';
axis equal
colorbar()
grid on
title('griddata interp method: nearest')
Another method would be to fill in the x, y, and intensity data for each corner of the range of data.
N = 5000;
th = 2*pi * rand(N,1);
x = r.*cos(th); % x coordinate
y = r.*sin(th); % y coordinate
intensity = hypot(10-x,10-y); % intensity values
% Fill in data for each corner of the range of data
% I'll use the minimum intensity for each corner - or you could use 0?
xBounds = [min(x,[],'all'), max(x,[],'all')];
yBounds = [min(y,[],'all'), max(y,[],'all')];
x(end+(1:4)) = xBounds([1 2 2 1]);
y(end+(1:4)) = yBounds([1 1 2 2]);
intensity(end+(1:4)) = min(intensity).*[1,1,1,1];
% interpolate in a grid
figure()
resolution = 500; % resolution of the interpolation
[Xq,Yq,intensityq] = griddata(x,y,intensity,...
linspace(min(x),max(x),resolution),...
linspace(min(y),max(y),resolution)');
% Plot results, use interpolated face color
p = pcolor(Xq,Yq,intensityq);
p.FaceColor = 'interp';
p.EdgeColor = 'none';
axis equal
colorbar()
grid on
title('Assign value to corners')
Adam Danz on 31 May 2024
If you want to keep the data within a circle, instead of interpolating from min to max of data range, you can interpolate based on points distributed within the circle.
opts = detectImportOptions('datapoints.xlsx');
opts = setvartype(opts,'double');
x = T.x;
y = T.y;
intensity = T.z;
% Interpolate gridded points within the circle
center = [mean(x,'all'), mean(y,'all')]; % Compute center of circle if not known
resolution = 1000; % resolution of the interpolation
[xg,yg] = meshgrid(linspace(min(x),max(x),resolution), linspace(min(y),max(y),resolution));
isOut = hypot(xg-center(1), yg-center(2)) > radius;
xg(isOut) = NaN;
yg(isOut) = NaN;
[Xq,Yq,intensityq] = griddata(x,y,intensity,xg,yg);
figure()
% Plot results, use interpolated face color
p = pcolor(Xq,Yq,intensityq);
p.FaceColor = 'interp';
p.EdgeColor = 'none';
axis equal
colorbar()
grid on
title('Sample points within a circle')

Shivani on 30 May 2024
Edited: Shivani on 30 May 2024
Hello @Sharon,
Please note that there are multiple methods for plotting a 2D map in MATLAB, and the most optimal approach depends on the specific characteristics of your data. I might not be able to suggest the most optimal method for plotting the graph described in your question.
Please refer to the code snippet below, which outlines one such approach for plotting a 2D map. This method utilizes `x` and `y` as coordinates, with `z` representing intensity. The snippet also includes code to interpolate the `z` values across the grid.
% Create a grid for x and y coordinates
[X, Y] = meshgrid(linspace(min(x), max(x), 100), linspace(min(y), max(y), 100));
% Interpolate z values on the grid
F = scatteredInterpolant(x', y', z');
Z = F(X, Y);
figure;
imagesc(X(1,:), Y(:,1), Z);
colormap(jet);
colorbar;
axis equal;
The following documentation links provide a deeper insight into the functions I've used in the above code snippet. Kindly refer to them for more information on how to customise the plot to your dataset:
Hope this helps!