Missing row/column when plotting a surface in MATLAB - matlab

Have a look at the following MATLAB code and the resulting surface plot. Maybe I am doing a stupid mistake, but there is actually a row and column missing. The variable z is a 10x10 matrix, but the plot shows only 9x9 elements. How to plot the whole 10x10 matrix?
z = randn(10,10);
t = 1:10;
x = 1:10;
figure;
surf(t,x,abs(z),'EdgeColor','none');
axis xy; axis tight; colormap(jet); view(0,90);

I think this is a misunderstanding about what surf does, i.e. what a surface plot is:
What you seem to be wanting is an actual image instead of a surface plot, where for the former pixels correspond to the underlying values. What you get with surf is a graphical representation of lines at a certain height (abs(z) in your case), i.e. between your desired image pixels. Note that there are 10x10 lines in your 9x9 plot.
What you want can be achieved visually e.g. by:
z = randn(10,10);
t = 1:10;
x = 1:10;
figure
imshow(abs(z),[]),
axis on, colormap(gca,jet)
colorbar
hope this helps!

Related

Overlay the data points which make-up a contour plot matrix on the same plot in MATLAB

Hope the title gave an adequate description of my problem. Basically, I am generating a contour plot in MATLAB using the contourf (x,y,z) function, where x and y are vectors of different lengths and z is a matrix of data with dimensions of x times y. The contourf plot is fine, however, I am looking to overlay this plot with the actual data points from the matrix z. I have tried using the scatter function, but I am getting an error message informing me that X and Y must be vectors of the same length - which they're not. Is there any other way to achieve this?
Thanks in advance for any help/suggestions!
I think meshgrid should help you.
z = peaks; %// example 49x49 z data
x = 1:20;
y = 1:49;
z = z(y,x); %// make dimensions not equal so length(x)~=length(y)
[c,h] = contourf(x,y,z);
clabel(c,h); colorbar;
[xx,yy]=meshgrid(x,y); %// this is what you need
hold on;
plot(xx,yy,'k.'); %// overlay points on contourf
Notice plot suffices instead of scatter. If you insist, scatter(xx(:),yy(:),10), for example, does the trick. Although my example isn't particularly interesting, this should hopefully get you started toward whatever you're going for aesthetically.

MATLAB - Plotting a smooth volume from 3D scatter plot data

So I have data in the form [x y z intensity] that I plot on a scatter3 figure with xyz axes. The colour of the data is used to dictate the intensity value. Problem is, using a scatter plot means the data points show up as discrete points. What I need, is a smooth shape - so I guess I need some kind of interpolation between the points?
I've tried using trisurf, but the problem with this one is that it interpolates between points that it shouldn't. So where I should have 'gaps' in my surface, it joins up the edges instead so it fills in the gaps. See the attached pics for clarification.
Does anyone have any suggestions?
The code I use is as below (the commented out scatter3 is what does the scatter plot, the rest does the trisurf):
% Read in data
dataM = csvread('3dDispersion.csv');
% scatter3(dataM(:,1), dataM(:,2), dataM(:,3), 5, dataM(:,4),'filled');
% Plot
hold on;
x = dataM(:,1);
y = dataM(:,2);
freq = dataM(:,3);
tri = delaunay(x,y);
h = trisurf(tri, x, y, freq);
% Make it pretty
% view(-45,30);
view(3);
axis vis3d;
lighting phong;
shading interp;
Use the boundary function in Matlab. This will apply a mesh similar to shrinkwrap over your points. In order to reduce the "gap closers", you will want to increase the "shrink factor".
Try K = boundary(X,Y,Z,0.9)
Where X, Y & Z are the vectors of your data points
https://www.mathworks.com/help/matlab/ref/boundary.html
You can then use trimesh or related surface plotting functions depending on how you want to display it.

Plotting shaded deviation of a line in Matlab

I would like to plot a line, and in grey-shaded X% deviation of a signal, in MATLAB. Then, I'd plot another signal and see (visually) how much of the second signal is outside the gret-shaded area.
The task I'd like to get help done is the shaded area: similar to the image attached below.
I am aware of similar solutions with errorbar, but I think this is a much clearer plot to visualize.
If for example I had:
x = 0:0.1:10;
y = 1 + sin(x);
What would the 5% grey-shaded plot of y look like? (that area?)
See this answer for an example: MATLAB fill area between lines
Do you have the error of y at each sample in x? Let's assume you have and the upper bound is in variable yu and the lower bound in variable yl. Then you could plot it using:
x = 0:0.1:10;
y = 1 + sin(x);
% I create some yu and yl here, for the example
yu = y+.1;
yl = y-.1;
fill([x fliplr(x)], [yu fliplr(yl)], [.9 .9 .9], 'linestyle', 'none')
hold all
plot(x,y)
fill(X,Y,ColorSpec,...) plots a polygon with edges specified in the first two parameters. You have to fliplr (flip left-right) the arrays, so that it correctly draws the shape of the area to be filled 'in a circle' around it. The [.9 .9 .9] is the colour specification, in this case a light grey. I removed the edge by setting no line, to make it even more similar to your desired plot. One detail: plot the filled area before plotting y, because the last plotted object goes on top of the others.

Plotting a rectangular matrix into a circle

I have generated a rectangular matrix with the azimouth angle changing with rows and the radius changing as you change column. These are meant to represent the relative velocities experienced by a rotating helicopter blade. This produces a matrix called Vmat. I want to plot this to appears in a circle (representing the rotation of the blade)
So far I have tried
[R,T] = meshgrid(r,az);
[x,y] = pol2cart(T,R);
surf(x,y,Vmat(r,az));
which should produce a contoured surface showing velocity as it changes with azimouth angle and radius but it comes up with dimension errors.
I don't mind if it is a 2d contour plot or 3d plot i guess both would be written in a similar way.
Thanks
James
The error is in writing Vmat(r,az), presuming that these are actual values of radius and azimuth, not indexes into your radius and azimuth. If you want to take only a subset of Vmat that's a slightly different matter, but this should work:
[R,T] = meshgrid(r,az); % creates a grid in polar coordinates
[x,y] = pol2cart(T,R); % changes those to cartesian for surf
surf(x,y,Vmat);
Alternatively you could do a contour plot:
h = polar([0 2*pi], [0 max(r)]); % set up polar axes with right scale
delete(h) % remove line
hold on
contour(x,y,Vmat);

How can I make a "color map" plot in matlab?

I have some data (a function of two parameters) stored in a matlab format, and I'd like to use matlab to plot it. Once I read the data in, I use mesh() to make a plot. My mesh() plot gives me the the value of the function as a color and a surface height, like this:
What matlab plotting function should I use to make a 2D mesh plot where the dependent variable is represented as only a color? I'm looking for something like pm3d map in gnuplot.
By default mesh will color surface values based on the (default) jet colormap (i.e. hot is higher). You can additionally use surf for filled surface patches and set the 'EdgeColor' property to 'None' (so the patch edges are non-visible).
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
% surface in 3D
figure;
surf(Z,'EdgeColor','None');
2D map: You can get a 2D map by switching the view property of the figure
% 2D map using view
figure;
surf(Z,'EdgeColor','None');
view(2);
... or treating the values in Z as a matrix, viewing it as a scaled image using imagesc and selecting an appropriate colormap.
% using imagesc to view just Z
figure;
imagesc(Z);
colormap jet;
The color pallet of the map is controlled by colormap(map), where map can be custom or any of the built-in colormaps provided by MATLAB:
Update/Refining the map: Several design options on the map (resolution, smoothing, axis etc.) can be controlled by the regular MATLAB options. As #Floris points out, here is a smoothed, equal-axis, no-axis labels maps, adapted to this example:
figure;
surf(X, Y, Z,'EdgeColor', 'None', 'facecolor', 'interp');
view(2);
axis equal;
axis off;
gevang's answer is great. There's another way as well to do this directly by using pcolor. Code:
[X,Y] = meshgrid(-8:.5:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
figure;
subplot(1,3,1);
pcolor(X,Y,Z);
subplot(1,3,2);
pcolor(X,Y,Z); shading flat;
subplot(1,3,3);
pcolor(X,Y,Z); shading interp;
Output:
Also, pcolor is flat too, as show here (pcolor is the 2d base; the 3d figure above it is generated using mesh):
Note that both pcolor and "surf + view(2)" do not show the last row and the last column of your 2D data.
On the other hand, using imagesc, you have to be careful with the axes. The surf and the imagesc examples in gevang's answer only (almost -- apart from the last row and column) correspond to each other because the 2D sinc function is symmetric.
To illustrate these 2 points, I produced the figure below with the following code:
[x, y] = meshgrid(1:10,1:5);
z = x.^3 + y.^3;
subplot(3,1,1)
imagesc(flipud(z)), axis equal tight, colorbar
set(gca, 'YTick', 1:5, 'YTickLabel', 5:-1:1);
title('imagesc')
subplot(3,1,2)
surf(x,y,z,'EdgeColor','None'), view(2), axis equal tight, colorbar
title('surf with view(2)')
subplot(3,1,3)
imagesc(flipud(z)), axis equal tight, colorbar
axis([0.5 9.5 1.5 5.5])
set(gca, 'YTick', 1:5, 'YTickLabel', 5:-1:1);
title('imagesc cropped')
colormap jet
As you can see the 10th row and 5th column are missing in the surf plot. (You can also see this in images in the other answers.)
Note how you can use the "set(gca, 'YTick'..." (and Xtick) command to set the x and y tick labels properly if x and y are not 1:1:N.
Also note that imagesc only makes sense if your z data correspond to xs and ys are (each) equally spaced. If not you can use surf (and possibly duplicate the last column and row and one more "(end,end)" value -- although that's a kind of a dirty approach).
I also suggest using contourf(Z). For my problem, I wanted to visualize a 3D histogram in 2D, but the contours were too smooth to represent a top view of histogram bars.
So in my case, I prefer to use jucestain's answer. The default shading faceted of pcolor() is more suitable.
However, pcolor() does not use the last row and column of the plotted matrix. For this, I used the padarray() function:
pcolor(padarray(Z,[1 1],0,'post'))
Sorry if that is not really related to the original post