How to plot a 3-column matrix as a color map in MATLAB? - matlab

I have a matrix containing the temperature value for a set of GPS coordinates. So my matrix looks like this :
Longitude Latitude Value
--------- -------- -----
12.345678 23.456789 25
12.345679 23.456790 26
%should be :
% x y z
etc.
I want to convert this matrix into a human-viewable plot like a color plot (2D or 3D), how can I do this?
3D can be something like this :
or just the 2-D version of this (looking from top z-axis).
What Have I Tried
I know MATLAB has surf and mesh functions but I cannot figure out how to use them.
If I call
surf(matrix(:,1) , matrix(:,2) , matrix(:,3));
I get the error :
Error using surf (line 75)
Z must be a matrix, not a scalar or vector
Thanks in advance for any help !
P.S : It would also be great if there is a function that "fills" the gaps by interpolation (smoothing, whatever :) ). Since I have discrete data, it would be more beautiful to represent it as a continous function.
P.S 2 : I also want to use plot_google_map in the z=0 plane.

A surprisingly hard-to-find answer. But I'm lucky that somebody else has asked almost the same question here.
I'm posting the answer that worked for me :
x = matrix(:,1);
y = matrix(:,2);
z = matrix(:,3);
xi=linspace(min(x),max(x),30)
yi=linspace(min(y),max(y),30)
[XI YI]=meshgrid(xi,yi);
ZI = griddata(x,y,z,XI,YI);
contourf(XI,YI,ZI)
which prints a nice color map.

One option that avoids unnecessarily gridding your data would be to compute the Delaunay triangulation of the scattered data points and then using a command like trisurf to plot the data. Here's an example:
N=50;
x = 2*pi*rand(N,1);
y = 2*pi*rand(N,1);
z = sin(x).*sin(y);
matrix = [x y z];
tri = delaunay(matrix(:,1),matrix(:,2));
trisurf(tri,matrix(:,1),matrix(:,2),matrix(:,3))
shading interp

Suppose your matrix is nx3. Then you can create the grid as follows:
xMin=min(myMat(:,1));
xMax=max(myMat(:,1));
yMin=min(myMat(:,2));
yMax=max(myMat(:,2));
step_x=0.5; %depends on your data
[xGrid,yGrid]=meshgrid(xMin:step_x:xMax,yMin:step_y:yMax);
Now, put your data in the third column to the appropriate indices, in the new matrix say, valMat.
You can use surf now as follows:
surf(xGrid,yGrid,valMat);
If you want interpolation, you can convolve a Gaussian kernel (maybe 3x3) with valMat.

Related

Matlab Surface Plot of Z^2 = Z type equation

i'm currently trying to plot this function:
Z^2 = (X.^2+Y.^2+2*w.*Z.*Y.*a)./(1-w^2*a^2)
Geogebra gives a lightcone https://en.wikipedia.org/wiki/Light_cone but crushes if i change the parameters a bit. I tried then matlab:
[X,Y] = meshgrid(-10:.5:10);
a=2;
w=1;
Z = (X.^2+Y.^2+2*w.*sqrt(abs(Z)).*Y.*a)./(1-w^2*a^2);
surf(X,Y,Z)
zlim([-5,5])
And it has too few points. I wish i could add some changing meshgrid, like (-5:.1:5), but it gives:
Arrays have incompatible sizes for this operation.
Probably due to sqrt(abs(Z)) in the equation. I don't know how to fix it.
Thanks
It's easier to directly generate the cone data with command cylinder
t = 0:pi/10:2*pi;
r =linspace(2,0,numel(t))
[X,Y,Z] = cylinder(r);
figure
hs1=surf(X,Y,Z)
Note that I have added the handle hs1 which is output of surf.
This way you can change any property of the generated cone surface explained in detail here :
https://uk.mathworks.com/help/matlab/ref/matlab.graphics.chart.primitive.surface-properties.html

plot diagonal slices of a 3D matrix with imagesc()

I'm new to Matlab and I really need help with the following problem:
I have a 255 x 255 x 255 matrix and I would like to plot its 2D slices with imagesc().
I understand that for plotting slices parallel to the x, y, z planes I could just specify the slice with something like matrix(:,:,i), but how would I do that if I want to plot the x = y slice, or in general any x = n*y slice?
What I'm thinking is to interpolate the matrix to those planes and then extract the slice, but I'm a little stuck on how.
Specifically for the x = y slice I've been trying to build a 2D matrix by using the diag() command for each z slice and by setting the new_matrix = matrix(i,i,:) for i=1:255, but that didn't seem to be working.
for that Matlab gave you slice !
[X,Y,Z] = meshgrid(-5:0.2:5);
V = X.*exp(-X.^2-Y.^2-Z.^2);
[xsurf,ysurf] = meshgrid(-2:0.2:2);
zsurf = xsurf/2+ysurf/2;
slice(X,Y,Z,V,xsurf,ysurf,zsurf)
and you can play with the camera view angle to emulate the imagesc feel, fir example try view(0, 90) after the code I wrote...
By the way... if you insists on doing the cut and using imagesc the way you wanted, this is how with the example I gave:
for n=1:size(X,1)
D(:,n)=squeeze(V(n,n,:));
end
imagesc(D)

how to create the surface plot with unequal vector size

clc
clear all
n1=rand(1,10);
n2=rand(1,10);
n3=rand(1,10);
n4=rand(1,10);
m1=rand(1,10);
m2=rand(1,10);
m3=rand(1,10);
m4=rand(1,10);
n=[n1;n2;n3;n4];
m=[m1;m2;m3;m4];
z=[0.1,0.2,0.3,0.4];
I want to create a surface plot using above data.for given z=0.1 plot(n1,m1), for z=0.2 plot(n2,m2)....how to combine all this to get a surface plot?
Mathwork's answer on how to plot scattered data should give you the best start.
I assume that your minimal example is not correct regarding z, because all data has to have the same dimension.
Fixing this, interpolation is one answer to your approach.
Following the mentioned link, it should look like this:
n = rand(4,10);
m = rand(4,10);
z=repmat([0.1 : 0.1 : 0.4]',1,size(n,2));
resolution = 0.01;
[xi,yi] = meshgrid(min(n):resolution:max(n), min(m):resolution:max(m));
zi = griddata(n,m,z,xi,yi);
surf(xi,yi,zi);

Matlab- Given matrix X with xi samples, y binary column vector, and a vector w plot all these into 3d graph

I have started to learn Machine Learning, and programming in matlab.
I want to plot a matrix sized m*d where d=3 and m are the number of points.
with y binary vector I'd like to color each point with blue/red.
and plot a plane which is described with the vertical vector to it w.
The problem I trying to solve is to give some kind of visual representation of the data and the linear predictor.
All I know is how to single points with plot3, but no any number of points.
Thanks.
Plot the points using scatter3()
scatter3(X(y,1),X(y,2),X(y,3),'filled','fillcolor','red');
hold on;
scatter3(X(~y,1),X(~y,2),X(~y,3),'filled','fillcolor','blue');
or using plot3()
plot(X(y,1),X(y,2),X(y,3),' o','MarkerEdgeColor','red','MarkerFaceColor','red');
hold on;
plot(X(~y,1),X(~y,2),X(~y,3),' o','MarkerEdgeColor','blue','MarkerFaceColor','blue');
There are a few ways to plot a plane. As long as w(3) isn't very close to 0 then the following will work okay. I'm assuming your plane is defined by x'*w+b=0 where b is a scalar and w and x are column vectors.
x1min = min(X(:,1)); x2min = min(X(:,2));
x1max = max(X(:,1)); x2max = max(X(:,2));
[x1,x2] = meshgrid(linspace(x1min,x1max,20), linspace(x2min, x2max, 20));
x3 = -(w(1)*x1 + w(2)*x2 + b)/w(3);
surf(x1,x2,x3,'FaceColor',[0.6,0.6,0.6],'FaceAlpha',0.7,'EdgeColor',[0.4,0.4,0.4],'EdgeAlpha',0.4);
xlabel('x_1'); ylabel('x_2'); zlabel('x_3'); axis('vis3d');
Resulting plot

plot a 3D matrix of concentrations in matlab with slice

I have a 3D matrix C=51x51x11 dimensions, obtained from a function in a separate script, the x,y,z represent length, depth and height, and the value represent a concentration per x,y,z point. I want to create a slice crossing x and another crossing y showing the difference in concentration by color. I have tried using ngrid and meshgrid but didn't work. may i have some help with this please?
Use slice()
C = randi(1,[51,51,11]);
x= 25; y = 25; z = 5;
sl = slice(C,x,y,z);
Using slice inside a function to make it easy to view in 3d:
function eslice(V,sx,sy,sz)
slice(V,sx,sy,sz)
shading interp
axis equal
axis vis3d
end
This is from my personal library, enjoy.