Plotting a heatmap with collected data

I have an image of a map with data allocated to different points on the map. Am I able to get co-ordinates of that image to place the data it's allocated spots and produce a heatmap over the image? Perhaps there is a better way of doing this?

4 Comments

Tell us what data you have and what's your expectations.
The data for each point is a value for the wifi signal strength recorded. I would like to have a heatmap to show the signal strength across the map using the recorded values.
Okay can be done...Have a look on geoscatter.
Thanks for the help. I will look into it.

Sign in to comment.

 Accepted Answer

Use function pcolor is another option.
clear;clc;
im = imread('map.png');
[Ny,Nx,Nc] = size(im);
f = figure(1);
ax = gca;
minSignal = 20;
maxSignal = 800;
X = repmat(linspace(minSignal,maxSignal,Nx),Ny,1); % Dummy data only
h = imagesc(ax,1:Nx, 1:Ny,im);
hold(ax,'on');
s=pcolor(ax,X);
s.FaceColor = 'interp';
s.FaceAlpha = 0.5;
s.EdgeColor = 'none';
axis(ax,'image');
cmap = colormap(ax,hsv);
cb = colorbar(ax);
title(cb,'Signal Level');
axis(ax,'off');

17 Comments

This looks promising. I appreciate the help, I'm having a little trouble implementing my data. It looks like this
[-104 -97 -105 -99 -95 -83 -95 -109 -104 -105 -82 -85 -89 -104 -97 -103 -83 -84 -84 -84]
-82 being the strongest signal and -104 being the weakest.
How would I find the coordinates of a spot in the image in order to apply the data points to each of them?
You may refer to this link: Array Indexing to understand more about the indexing in MATLAB.
Suppose your data is across the map in lateral direction (from left to right).
I would resize the image in this direction so that I am able to put the data without any interpolation.
In the following example, the number of row and column of the original image (Variable im) are 342 and 430 respectively. I don't care the number of rows since your data has only 1 row, so I resize the number of columns from 430 to 420 so that all data can be fitted just by repeating the data.
The next step is to repeat the signal to match the number of the columns in the image. For each signal, it occupy 20 columns in the image. After that, repeat the expanded signal in row direction, which is 342 in this case.
clear;clc;
im = imread('map.png');
[Ny,Nx,Nc] = size(im); % Determine the size of the image
%
Sig = [-104 -97 -105 -99 -95 -83 -95 -109 -104 -105 -82 -85 -89 -104 -97 -103 -83 -84 -84 -84];
Nz = length(Sig); % Number of data in the signal
extra_Nx = mod(Nx,Nz);
im_resize = imresize(im, [Ny,Nx-extra_Nx]); % Resize the image based on number of the signal
[~,Nx_new,~] = size(im_resize);
rep_Sig = repelem(Sig,1,Nx_new/Nz); % Repeat signal to fit column number of the image
rep_Sig = repmat(rep_Sig,Ny,1); % Repeat signal to fit row number of the image
%
f = figure(1);
ax = gca;
h = imagesc(ax,1:Nx_new, 1:Ny,im_resize);
hold(ax,'on');
s=pcolor(ax,rep_Sig);
s.FaceColor = 'interp';
s.FaceAlpha = 0.3; % You may adjust this value
s.EdgeColor = 'none';
axis(ax,'image');
cmap = colormap(ax,flipud(autumn)); % Inverse the colormap darker color represent higher signal
cb = colorbar(ax);
title(cb,'Signal Level');
%% The following is only for display only, you may not need the following lines
xtext = linspace(Nz/2+1,Nx_new-Nz/2,Nz);
ytext = repelem(Ny/2,1,Nz);
text(ax,xtext,ytext,num2str(Sig'),'HorizontalAlignment','center','FontSize',6);
axis(ax,'off');
Thanks for the response, please refer to this link:
My data has an X and Y component. Which is where I'm finding the most difficulties with. I have my map and where the data should be (see attached png for example map). I just dont know how to get it's X and Y co-ordinates to arrange it into an array as shown in the link above. Apologies for any mixups, I am fairly new to MATLAB in general.
Now I understand:
clear; clc;
data = imread('map.png'); % Read the image
BW1 = ~rgb2gray(data); % Convert to gray scale and invert
SE = strel('disk',5);
BW2 = bwareafilt(BW1,1); % Find the largest rectange
CC = bwconncomp(imdilate(BW1-BW2,SE)); % Use image dilate
s = regionprops(CC,'Centroid','BoundingBox'); % Find the centroid and bounding box (optional)
pos = round(cat(1,s.Centroid)); % Combine the centroid as a matrix
imshow(data)
hold on
plot(pos(:,1),pos(:,2),'g*') % Plot the detected location
pos
pos = 12×2
95 88 96 206 97 349 224 212 228 101 248 344 411 90 415 211 423 330 636 346
Additionally I've realised you can find points on an image using [ xi,yi ] = gepts, when I select more than 12 points, the X coordinates are returned as low decimal values. Why is this?
It depends how you extract the blobs from the image.
You may highlight your map with distinct color as below, so that it is easy to extract the correct location of your points.
data = imread('map2.png');
[R,G,B] = imsplit(data);
maskR = R>220;
maskG = G>180;
maskB = B<20;
BW1 = maskR & maskG & maskB;
CC = bwconncomp(BW1);
s = regionprops(CC,'Centroid');
pos = round(cat(1,s.Centroid));
imshow(data)
hold on
plot(pos(:,1),pos(:,2),'g*')
Following the method as you mentioned, I get the following:
Not sure how to get mine to look like the example. I have inputted data and co-ordinates but there seems to be another issue like the image you displayed.
Simon Chan
Simon Chan on 11 Mar 2022
Edited: Simon Chan on 11 Mar 2022
Possible to elaborate the issue?
You may exclude the outer area and get this:
Apologies. What I am trying to do is use getpts to get the coordinates of the image displayed which seems to be working so far:
figure
imshow('map.PNG')
[x,y] = getpts
Then with the coordinates received, I apply them to the X and Y like shown in the link I sent previously, along with the data collected for each point.
strength = [-90 -90 -90 -90 -40 -20 -22.4 -45 -35 -41 -44 -55 -40 -75 -26]';
X = [10 550 550 10 50 234 393 129 237 328 448 225 344 457 477]';
Y = [10 10 410 410 293 210 202 132 130 142 141 272 268 274 200]';
(X and Y values from command window after using getpts)
Then with the remainder of the code shown in the example link, produce a heatmap of my desired image.
Is this possible or am I doing it incorrecty?
Additionally, my X co-ordinates show up in the command window as decimal points when I select more than 12 points on the image once it is displayed.
use function round
xi = [234.6; 563.4];
xi = round(xi)
xi = 2×1
235 563
Thank you so much for the help. I really appreciate it.
Lastly, I would just like to ask. Am I able to get the getpts co-ordinates outputted as an array in the command window?
Like this: xi = [ 43 335 644 891 889 669 ]
Not this:
xi =
43
335
644
891
889
669
Thank you.
Do transpose when you want the data to switch from a column vector to row vector and vice versa.
xi = [43; 335; 644; 891; 889; 669] % Coordinates frm getpts
xi = 6×1
43 335 644 891 889 669
Do the transpose when you want to dispay it in command window.
xii = transpose(xi) % Transpose
xii = 1×6
43 335 644 891 889 669
Everything is complete. Thanks for all the help.
Congratulations.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2021a

Asked:

on 10 Mar 2022

Commented:

on 16 Mar 2022

Community Treasure Hunt

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

Start Hunting!