How to plot a 3D heatmap or histogram over an image in matlab? - matlab

I have this type of data:
Data = [1:1:9; 1 2 3 4 5 6 7 8 9; 1 2 3 4 5 6 7 8 9 ;1 2 3 4 5 6 7 8 9;1 2 3 4 5 6 7 8 9];
Where the first entry is the zone of interest (9 zones total) and the remaining 4 array entries are how long something stayed in the zone (just arbitrary now for this question.
I want to plot how long each thing is in each zone on a picture of a map as a 3d "heatmap" style plot. The map is divided into a 3x3 grid like so:
1 2 3
4 5 6
7 8 9
How do I plot this? I have tried the contour and surf functions but I am not sure how I would map them to the grid. I would like to overlay the graph on a map picture as my final step but just getting the graph up and running would be great!

You can use imagescfor the 2D version or bar3 for the 3D version, in this example I created some subplots, but of course you are free to change this option.
Data = [1:1:9; 1 2 3 4 5 6 7 8 9; 1 2 3 4 5 6 7 8 9 ;1 2 3 4 5 6 7 8 9;1 2 3 4 5 6 7 8 9];
M = zeros(3,3);
2D
for ii = 2:size(Data,1)
subplot(2,2,ii-1)
M(1:end) = Data(ii,:);
imagesc(M)
colormap jet
shading flat %for an exact result
% shading interp %for a smooth result
end
figure
3D (even if I think that the 3D view is useless)
for ii = 2:size(Data,1)
subplot(2,2,ii-1)
M(1:end) = Data(ii,:);
h{ii} = bar3(M)
colorbar
for k = 1:length(h{ii})
zdata = h{ii}(k).ZData;
h{ii}(k).CData = zdata;
h{ii}(k).FaceColor = 'interp';
end
end

I'm not sure if this is the kind of plot that you want, but you could use Delaunay Triangulation to map your duration data as a surface over your grid points. The MatLab file exchange has a nice function for mapping something using this method.
Making Surface Plots from Scatter Data

Related

Rotating a matrix to create a spiral order of values

How do I rotate a matrix to create a spiral order of values?
For example,
12 4 2
8 3 11
6 7 2
I am supposed to to display 12 4 2 11 2 7 6 8 3 but I don't know how to terminate at the 1st row and rotate the function 90 degrees. Thanks in advance for the help.
Hint:
Check the spiral function:
spiral(n) is an n-by-n matrix with elements ranging
from 1 to n^2 in a rectangular spiral pattern.
Use its output to build an index into the original values. You may also need sort, as well as fliplr to reverse the order of values.
See the code after you've given it a try.
x = [12 4 2; 8 3 11; 6 7 2];
t = fliplr(spiral(sqrt(numel(x))));
[~, ind] = sort(t(:));
result = fliplr(x(ind).');
A =[12 4 2;...
8 3 11;...
6 7 2];
B=[];
for ii=1:5
B = [B A(1,:)];
A(1,:)=[];
A=rot90(A);
end
B
B =
12 4 2 11 2 7 6 8 3

Matlab adjusting heat map axes and colors

I'm trying to create a heat map which is something I'm not very familiar with. I have a large matrix of the form:
One=
[0 2 4 6 8
2 1 3 5 6
4 5 8 3 1
6 2 7 4 8
8 3 9 5 4]
And I want to create a heat map such that the topmost row and the leftmost column are the axes.
So far I've managed this:
figure(1)
Plot = One;
colormap('hot');
imagesc(Plot);
I've also noticed that in the 'hot' colormap, the small numbers are very dark and the large numbers are white. Is there a way to reverse that?
Here a good start:
One = ...
[0 2 4 6 8
2 1 3 5 6
4 5 8 3 1
6 2 7 4 8
8 3 9 5 4];
figure();
imagesc(One(1,:), One(:,1), One(2:end,2:end));
get(gca(), 'ydir', 'normal')
colormap(flipud(hot()));
colorbar();
Notice that the x & y axis are larger than the data, so perhaps one needs to exclude One(1,1):
figure();
imagesc(One(1,2:end), One(2:end,1), One(2:end,2:end));
get(gca(), 'ydir', 'normal')
colormap(flipud(hot()));
colorbar();
Generate the colormap with the hot function and flip it upside down with flipud:
colormap(flipud(hot))
By default this produces 64 colors. If you want to specify a different number, say 128, use
colormap(flipud(hot(128)))

plot two histograms (using the same y-axis) and a line plot (using a different y-axis) on the same figure

How can I plot two histograms (using the same y-axis) and a line plot (using a different y-axis) on the same figure? I am using Matlab 2014b. I am aware of this but it seems to only work for bar plots?
This is my histogram code:
A = [1 2 2 2 3 4 5 5 5 5 5 5 5 5 5 6 6 6 7 7];
B = [6 6 6 7 7 7 7 7 7 7 8 8 8 9 9 10 10];
hist(A,7);
hold on
hist(B,7);
h = findobj(gca,'Type','patch');
set(h(1),'FaceColor','b','EdgeColor','b','facealpha',0.2)
set(h(2),'FaceColor','r','EdgeColor','r','facealpha',0.2)
xlabel('Day','fontsize',14)
ylabel('Frequency','fontsize',14)
xlim([1 10])
Now say I have these data:
Day = [1 2 3 4 5 6 7 8 9 10];
Prevalence = [3 2 4 8 5 6 7 8 9 5];
I want to plot these data (plot(Day,Prevalence)) using the right y-axis.
Thanks.
I think this workaround will do what you want.
Basically create a new axes at the same position than the one in which the histograms are plot, however set its color property to 'none' and the YAxisLocation to the right. You can then assign the new axes the properties you want.
Code:
clear
clc
%// ====================
%// Your code
A = [1 2 2 2 3 4 5 5 5 5 5 5 5 5 5 6 6 6 7 7];
B = [6 6 6 7 7 7 7 7 7 7 8 8 8 9 9 10 10];
hist(A,7);
hold on
hist(B,7);
h = findobj(gca,'Type','patch');
set(h(1),'FaceColor','b','EdgeColor','b','facealpha',0.2)
set(h(2),'FaceColor','r','EdgeColor','r','facealpha',0.2)
xlabel('Day','fontsize',14)
ylabel('Frequency','fontsize',14)
xlim([1 10])
%// ====================
Day = [1 2 3 4 5 6 7 8 9 10];
Prevalence = [3 2 4 8 5 6 7 8 9 5];
%// Get the current axes position to place the new one.
AxesPos = get(gca,'Position');
hold on
hax2 = axes('Position',AxesPos);
%// Plot the data
plot(Day,Prevalence,'--k','LineWidth',4,'Parent',hax2)
%// Set properties of the axes.
set(hax2,'Color','none','YAxisLocation','right','XTick',[],'XTickLabel','','YLim',[0 15])
ylabel('Prevalence','FontSize',16)
%// Rotate the label to correct orientation
LabelPos = get(get(hax2,'YLabel'),'Position');
set(get(hax2,'YLabel'),'Position',[LabelPos(1)+.2 LabelPos(2) LabelPos(3)],'Rotation',-90)
Output:
Note that it's far from perfect ...for example the left border of the first axes is not visible...that could be fixed by playing around with the position of the new axes. Hopefully it does the job for you!

matlab colormap with three columns

I want to draw a color map with three columns in matlab.
I can draw with plot3 like below,
x = [1 1 1 1 2 2 2 2 4 4 4 4 5 5 5 5 9 9 9 9];
y = [2 3 4 5 5 6 7 8 4 5 6 7 1 2 3 4 7 8 9 10];
z = [1 3 2 4 5 6 7 3 9 8 8 9 2 4 3 5 1 2 3 1];
plot3(x, y, z, 'o')
But how can I draw 2D color map with three columns?
Option 1:
If I understand you correctly you want to draw a 2D array (say m(x,y)) where the color is given by z. this is how:
m=zeros(max(x),max(y)); % preallocate m according to values of x,y
m(sub2ind(size(m),x,y))=z; % assign z-values to the x,y coordinates
imagesc(m) % plot
colormap(pink(max(z))); % set colormap with the dynamic range of z.
% you can replace it with jet or whatever...
colorbar % add a colorbar
Option 2:
you really just want to create am RGB colormap from x,y,z:
cmap=[x(:) y(:) z(:)]./max([x(:);y(:);z(:)]);
imagesc(peaks(100));
colormap(cmap);

matlab show change in 3D data

What I would like to do is visualise the change in 3 dimensional data. For example i have two arrays:
before:
x y z
1 2 3
4 5 6
7 8 9
after:
x y z
2 2 3
5 5 6
8 8 9
I would like for the plot to be 3D scatter data like the folowing:
I know about quiver3 which plots norms but i am not sure how to do it from just 2 lists of X, Y, Z points.
The actual data will be much more complex.
Thanks for your help.
Arrow.m is available from the Matlab File Exchange that makes drawing arrows really easy:
>> A = [1 2 3; 4 5 6; 7 8 9];
>> B = [2 2 3; 5 5 6; 8 8 9];
>> hold on
>> scatter3(A(:,1), A(:,2), A(:,3))
>> scatter3(B(:,1), B(:,2), B(:,3))
>> arrow(A, B)
Otherwise, take a look at other answers to this question.