How to get surf to plot all points and not ignore last row and column?
12 views (last 30 days)
Show older comments
I have the following: lat = a matrix of latitudes, lon = a matrix of longitudes, depth = a matrix of depths, and slip = a matrix to tell "surf" what color to assign to each lat, lon, depth.
I then simply plot it using surf(lon,lat,depth,slip).
When I do this, though, instead of using the lat, lon, depth coordinates as the center of each grid, it uses the specified point as the top right of the grid. It also doesn't plot the last row or column of data. When I use lat, lon, depth, and slip as vectors rather than matrices, and use scatter3(lon,lat,depth,'.','CData',slip), I get all the rows and columns to plot correctly.
How can I get surf to plot the points correctly and not eliminate my last row and column of data?
The documentation for surf says "In this case, C can be the same size as X, Y, and Z and its last row and column are ignored", but it doesn't say how to stop it from doing this. I don't want to shade with interpolation. Anyone know of a workaround?
To better illustrate my problem, here's a picture of what I'm trying to get at: <http://s255.photobucket.com/albums/hh137/ozziemo/Misc/?action=view¤t=PlottingProblem.jpg> followed by actual plots of one of my data sets.
Please help. I read through tons of Matlab help files and couldn't find anything. I'm not an expert in this, so please be gentle in your explanations as well, please. Thank you so much!
3 Comments
Jan
on 26 Jul 2011
@Jessica: I like the drawing, which is more descriptive than 127 words. Such pictures would be so helpful in a lot of other questions here... Therefore I've voted your question and this is my personal *question of the week* :-)
Kelly Kearney
on 26 Jul 2011
If you only have data for the center of each cell, what do you want to do at the edges? Extrapolate the data? And how far in each direction? If your vertex data is one cell larger than your color data, i.e.
lon: nx x 1
lat: ny x 1
depth: nz x 1
slip: nx-1 x ny-1 x nz-1
or similar meshed data, then the NaN-padding should work. But as you state the problem above, there's not enough info to construct a surface.
Answers (4)
Jan
on 26 Jul 2011
If you know, that the last row and column are ignore, what about appending a row and column filled by zeros or NaNs?
Patrick Kalita
on 26 Jul 2011
I understand that you want to draw a surface where each face is centered at a certain location and colored appropriately. It sounds simple enough. I'll just show a quick sketch of how it could be accomplished, and maybe that will help to illustrate why it is not easy to solve this problem in general.
Let's say I have this vertex and color data:
x = [1 2 3; 1 2 3; 1 2 3];
y = [1 1 1; 2 2 2; 3 3 3];
z = x + y;
c = magic(3);
Clearly this is not what you are looking for:
surf(x, y, z, c);
What we need to do is produce another set of x, y, and z values such that centers of the resulting surface faces are at the original x, y, z locations. Here it is for this data set. Notice that the original x is 3-by-3 and the new one is 4-by-4:
x2 = [0.5 1.5 2.5 3.5; 0.5 1.5 2.5 3.5; 0.5 1.5 2.5 3.5; 0.5 1.5 2.5 3.5];
y2 = [0.5 0.5 0.5 0.5; 1.5 1.5 1.5 1.5; 2.5 2.5 2.5 2.5; 3.5 3.5 3.5 3.5];
z2 = x2 + y2;
A few things to note here. First, since my x and y values were uniformly spaced that made it easier to figure out where to put the intermediate values of x2 and y2. Also note that the new values go outside the range of the original values. Second, I took a shortcut here and just recomputed z2 from x2 and y2. If z2 were measurements and recomputing is not possible, then you'd have to do some interpolation and extrapolation (because some of the new points are outside the range of the old points).
Now, I just need to make a new color data array with the appropriate size by padding the original array:
c2 = zeros(size(x2));
c2(1:3, 1:3) = c;
Finally, I can create a surface with my new vertices and colors:
surf(x2, y2, z2, c2);
Also, just as a side note, MATLAB does use all of the color values when face color interpolation is used:
x = [1 2 3; 1 2 3; 1 2 3];
y = [1 1 1; 2 2 2; 3 3 3];
z = x + y;
c = magic(3);
surf(x, y, z, c);
shading interp
But I understand that may not be the visual effect you are looking for.
Fangjun Jiang
on 26 Jul 2011
[x,y]=meshgrid(1:4,1:4);
z=repmat(1:4,4,1);
figure(1);scatter3(x(:),y(:),z(:));
figure(2);surf(x,y,z);
I see nothing wrong.
Taufik Valiante
on 21 Dec 2017
Duplicate the last row and column and use shading interp, and will be good to go.
0 Comments
See Also
Categories
Find more on Annotations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!