How to get surf to plot all points and not ignore last row and column?

17 views (last 30 days)
Jessica on 26 Jul 2011
Answered: Taufik Valiante on 21 Dec 2017
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: <> 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!
Kelly Kearney
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.

Sign in to comment.

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
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.
  1 Comment
Jessica on 26 Jul 2011
Thanks so much for your post. I did something along the lines of what you did for now, but they're not uniformly spaced, I had to make up values that go outside the original range, which could be problematic if the surface (in my case, a fault) curves or changes dramatically at the ends, and z's are measurements (depth), so they cannot be recomputed.
You're completely right "It sounds simple enough" and that's what's making it so frustrating! I really, really, really don't want to use shading interp, but in order to be true to the layout of the data, I may have to.
I'll try changing some of the details of what I have right now based on what you've posted here. Thanks. :)

Sign in to comment.

Fangjun Jiang
Fangjun Jiang on 26 Jul 2011
I see nothing wrong.
  1 Comment
Jessica on 26 Jul 2011
Assuming every point in z is meaningful, I see a lot wrong. In figure 2 only 9 of your 16 points are plotted with their colors...this is the exact problem I'm having.

Sign in to comment.

Taufik Valiante
Taufik Valiante on 21 Dec 2017
Duplicate the last row and column and use shading interp, and will be good to go.

Community Treasure Hunt

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

Start Hunting!

Translated by