Plot a 3D matrix (1 dependent & 2 independent variables)

I have a matrix with 2 independent variables (X and y) which have given data. I want to plot this data with X and Y (in the X and Y dimensions) and the corresponding data point in the Z direction so that it appears like a contour map with the independent variables giving the location and the dependent giving the magnitude. Does anyone have an idea how I could do this? Cheers

 Accepted Answer

You could use mesh or surf. As an example, consider X and Y verctors, with Z defined as sin(X) + cos(Y).
X = linspace(0,2*pi,20);
Y = linspace(0,pi,10);
[X,Y] = meshgrid(X,Y);
Z = sin(X) + cos(Y);
surf(X,Y,Z)

9 Comments

Em
Em on 4 Jan 2021
Edited: Em on 4 Jan 2021
Thank you! You're right, it definitely looks like surf or mesh are the way to go. The difference with my data to this is that it's only experimentally related to X and y.
I've tried plotting:
X = linspace(0,10,150);
Y = linspace(0,5,70);
[X,Y] = meshgrid(X,Y);
surf(X,Y,mlowr)
but I get the error message 'Data dimensions must agree.'
Then when I try plotting just surf(mlowr), it looks like there is something wrong with my dimensions because the Z value should not exceed 100, a mesh and colour matching the height as in your plot would be ideal. ( x should vary between 50 and 150, y should vary between 40 and 70, so something is going very wrong with my attempt here)
My initial thought would be that SP should be the values that correspond to the columns of mlowr, P should be the values that correspond to the rows of mlowr. You don't need D. However, it's hard to say specifically what you should do without seeing your data.
Please save your data to a mat file and attach it to your post using the paperclip icon.
Thanks a lot! Only 'mlowr' is the matrix worth looking at here. It's the last column that I want to take the height values.
Ok, I see a couple things. First, Z must be a matrix, not a vector. If I assume the first column contains the row values for Z and the second column contains the column values, then I must reshape the data so that Z is a matrix with rows that match unique values in X and columns that match unique values in Y. There is a reshape function just for this.
I also noticed your values, while grouped, were not in ascending or descending order. When you are creating a plot, you result will look better if your independent variable(s) are strictly increasing or decreasing (if that is appropriate for your data. Yours goes from 150 to 75 to 125. This might be why your results look off.
Here is how I did it.
load lowresmesh.mat mlowr
% Sortrows so
mlowr = sortrows(mlowr,[1 2 3]);
X = reshape(mlowr(:,1),3,[]);
Y = reshape(mlowr(:,2),3,[]);
Z = reshape(mlowr(:,3),3,[]);
surf(X,Y,Z,'FaceColor',"interp")
colorbar
That looks great, hopefully I can get to a similar point soon!
When I try to run the code I get this error message popping up:
Error using matlab.graphics.chart.primitive.Surface/set
Error setting property 'FaceColor' of class 'Surface':
Color value must be a 3 element numeric vector
Error in matlab.graphics.chart.internal.ctorHelper (line 8)
set(obj, pvpairs{:});
Error in matlab.graphics.chart.primitive.Surface
Error in surf (line 150)
hh = matlab.graphics.chart.primitive.Surface(allargs{:});
I'm running exactly the same code and I reloaded the workspace too
I've tried running the following code as a test and it works just fine but the colours you used really make the slopes a lot clearer
mlowr1 = sortrows(mlowr,[1 2 3]);
X = reshape(mlowr1(:,1),3,[]);
Y = reshape(mlowr1(:,2),3,[]);
Z = reshape(mlowr1(:,3),3,[]);
surf(X,Y,Z,'FaceAlpha',0.5)
Sorry. You're using an older version of MATLAB that doesn't support double quotes on values. Change the surf command to use single quotes.
surf(X,Y,Z,'FaceColor','interp')
Thanks so much! Its working perfectly now.
I was wondering if there was also a way for me to add the mesh to this plot to make the contours more visible? I tried adding the line 'alpha 0.5' just below and it is helping clarity to some degree.
Part of the issue with your visualization is that there are so few points. It makes it hard to see. If changing alpha works for you, that's good. Another option might be to use interpolation to increase the number of points, giving more of a surface appearance to your figure. this can be done with scatteredInterpolant. Just be careful, as interpolation might not result in accurate results.
load lowresmesh.mat mlowr
% Sortrows so
mlowr = sortrows(mlowr,[1 2 3]);
F = scatteredInterpolant(mlowr(:,1),mlowr(:,2),mlowr(:,3));
[xq,yq] = meshgrid(linspace(min(mlowr(:,1)),max(mlowr(:,1)),15),linspace(min(mlowr(:,2)),max(mlowr(:,2)),9));
zq = F(xq,yq);
surf(xq,yq,zq,'FaceColor','interp')
Thank you!! This looks exactly as I hoped.

Sign in to comment.

More Answers (0)

Products

Release

R2018a

Asked:

Em
on 4 Jan 2021

Edited:

on 4 Jan 2021

Community Treasure Hunt

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

Start Hunting!