Reputation: 1235
I want to plot a 3d scatter plot with a surface plot on the same figure, so that I end up with something like this:
I would have thought that the code below might have achieved what I wanted but obviously not. I have x
, y
and z
data to plot a scatter3
:
x = [1 1 1 1 0.95 0.95 0.95 0.95 0.85 0.85 0.85 0.85 0.8 0.8 0.8 0.8 0.75 0.75 0.75 0.75]';
y = [0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1]';
z = [0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3]';
scatter3(x,y,z)
hold on
And now add a surface??
p = [x y z];
surf(p)
Any ideas? Thanks.
Upvotes: 3
Views: 9990
Reputation: 167
I had to deal with the same problem; I thought it might be still useful to answer this question
You need to create a compatible z-axis/matrix. I wrote
scatt2surf
to convert scatter data to surfaces. I hope it helps.
clear all;clc
xx = [1 1 1 1 0.95 0.95 0.95 0.95 0.85 0.85 0.85 0.85 0.8 0.8 0.8 0.8 0.75 0.75 0.75 0.75];
yy= [0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1];
zz= [0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3];
[x1,y1,z_surf]=scatt2surf(xx,yy,zz);
figure(3)
surf(x1,y1,z_surf);
xlabel('\it X');ylabel('\it Y');zlabel('\it Z');
colormap(hot)
hold on
scatter3(xx,yy,zz,[],zz,'o','filled','MarkerEdgeColor','none');
grid on;
function [x1,y1,z_surf]=scatt2surf(xx,yy,zz)
x1= unique(round(xx,7));
y1=unique(round(yy,7));
z_surf=ones(length(x1),length(y1));
for i=1:length(x1)
for j=1:length(y1)
indx=[xx==x1(i) & yy==y1(j)];
z_surf(i,j)=zz(indx);
end
end
z_surf=z_surf';
end
Upvotes: 0
Reputation: 31
The problem is that surf is treating your matrix p as a 2D array of z values, with integer values for x & y. Fortunately, surf has more than one way to enter values (see http://au.mathworks.com/help/matlab/ref/surf.html).
Try this:
x = [1 1 1 1 0.95 0.95 0.95 0.95 0.85 0.85 0.85 0.85 0.8 0.8 0.8 0.8 0.75 0.75 0.75 0.75]';
y = [0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1 0.3 0.2 0.15 0.1]';
z = [0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3 0.1 0.15 0.2 0.3]';
xr = reshape(x, 4, 5);
yr = reshape(y, 4, 5);
zr = reshape(z, 4, 5);
surf(xr, yr, zr)
xlabel('x')
ylabel('y')
zlabel('z')
In this case, surf expects a 2D array of x, y, and z values (as they would appear if looking at them top down). This way, surf knows which vertices to connect into a surface. Fortunately this can be easily achieved with your data by simply reshaping the vectors into matrices.
In future, if all your points lie on the same x and y coordinates, you could replace xr with [1, 0.95, 0.85, 0.8, 0.75] and yr with [0.3, 0.2, 0.15, 0.1] and surf will convert them into arrays for you.
Upvotes: 3