Doug's MATLAB Video Tutorials

November 2nd, 2007

Advanced MATLAB: Surface plot of nonuniform data

Two minute video shows how to fit a surface to nonuniform data. Real data is not always on a nice X,Y grid, but the MATLAB commands SURF and MESH expect them to be. GRIDDATA and MESHGRID help to fix this.
Find the files here. PodCast here Other videos have been gathered here: http://blogs.mathworks.com/pick/category/video/

24 Responses to “Advanced MATLAB: Surface plot of nonuniform data”

  1. Masatoshi KASUGA replied on :

    Dear Sir:

    I am very grad to find the program of “advanced-matlab-surface-plot-of-nonuniform-data”, but I could not run it
    because of no-coincide of matrix dimension.
    Would you please inform me of a mistake I coded (copied).

    Best Regards,
    ————————

    %3D graph for nonuniform_data
    x=rand(100,1)*16-8;
    y=rand(100,1)*16-8;
    r=sqrt(x.^2+y.^2)+eps;
    z=sin(r)./r;
    %
    xlin=linspace(min(x),max(x),33);
    ylin=linspace(min(y),max(y),33);
    [X,Y]=meshgrid(xlin,ylin);
    Z=griddata(x,y,z,X,Y,’cubic’);
    %
    mesh(X,Y,Z); % interpolated
    axis tight; hold on
    plot3(x,y,z,’.',’MarkerSize’,15)
    %%surf(X,Y,Z)

  2. paul replied on :

    I copied the code from you message and it worked perfectly on my side! – sorry!

  3. Doug replied on :

    The code you pasted here worked exactly right for me too. I am not sure what to do for you.

    Sorry,
    Doug

  4. Doug replied on :

    Greg pointed me to this solution he wrote a while back that might be of interest also:

    Tech Note 1212 – Using MESHGRID and GRIDDATA to Fit Vector Data and Plot Unevenly Spaced Data http://www.mathworks.com/support/tech-notes/1200/1212.html

  5. Els replied on :

    Dear Doug,

    This info about making a surface plot was very usefull for me. In stead of the formule that you used to produce some points, I used 4 XYZ-coordinates that result in an surface in 3D. Is there an easy way to calculate the surface area of this created object?

    Best regards,
    Els

  6. Doug replied on :

    Els,

    There is no built in function to do this, but knowing the X,Y,Z of each point in the mesh, you should be able to calculate the area of each four point patch. From there, summing should be easy to know the whole area.

    Doug

  7. venkat replied on :

    I have multiple [x,y,z] matrices of my data with which i want to plot the surface using a 7th order polynomial, how can I do that??

  8. Doug replied on :

    Venkat,

    I am not sure that I understand the question. If you have x,y,z triples, you just plot them. Are you trying to fit a polynomial to them? That would imply a two dimensional dataset. Are you trying to fit some kind of a surface to the data?

    You might be best off looking here:

    http://blogs.mathworks.com/pick/how-to-get-help/

    It shows how to ask for help at the bottom.

    Doug

  9. Sia replied on :

    i have a question regarding (x,y,z) set of data points. i have a file with x,y,z coordinates (z is depth) and I would compute the dip at each point in both x and y directions. my data has the following conditions:

    1- difference between each pair of points in both x and y directions are constant, in other words, delta_x and delta_y are constant (but delta_x ~= delta_y; is not equal which is not important).

    2- my surface points could be removed somewhere meaning that in those points i don’t have data.

    3- i would use second order of derivative to compute dip at each point.

    4- i would have the same number of dip as number of my points (or data ).

    i would appreciate your help.

  10. dhull replied on :

    @sia

    I think you want gradient:

    http://www.mathworks.com/access/helpdesk/help/techdoc/ref/gradient.html

  11. Nitesh replied on :

    Hi,

    I have data set which contains x,y and z coordinates of a finite element model. I want to plot mesh for this model. But the function ‘mesh’ in matlab requires the Z as Z(i,j) where i is size of x and j is size of y. I tried to generate Z(i,j) using
    [X,Y]=meshgrid(x,y);
    Then,
    Z=griddata(N2(:,2),N2(:,3),N2(:,4),X,Y,’cubic’);
    mesh(X,Y,Z);
    When I am plotting the mesh, it shows me that I have duplicate values. My z coordinate data has duplicate z coodrinates like, it has 0 for few and 0.5 for few, like wise.
    Can you please suggest me how to plot this data set?
    Thanks
    Nitesh

  12. dhull replied on :

    @Nitesh,

    To be clear, please give the sizes of all your variables (ie. How big are x,y,z. How are they related to one another) Is the data regularly spaced in x and y? Is this a sheet? (only one Z value for any given point in X and Y)

    Doug

  13. Nitesh replied on :

    Hi Doug,
    The size of my data set is 3080

    My Data looks like this,

    1 69.5946900000000 204.716400000000 0
    2 69.1238900000000 204.159900000000 0
    3 75.1291900000000 199.044600000000 0
    4 69.2183100000000 199.836300000000 0
    5 73.2698700000000 198.974500000000 0
    6 69.6076700000000 198.868100000000 0
    7 73.7034400000000 198.942700000000 0
    8 72.3838800000000 199.717100000000 0
    9 71.2137500000000 201.124400000000 0
    10 69.2146700000000 199.352700000000 0
    .
    .
    .
    172 74.8000000000000 214.500000000000 0.5
    173 75.2000000000000 215 0.5
    .
    .
    .
    1902 67.5000000000000 197.500000000000 1
    1903 67.5000000000000 198 1
    1904 74.4000000000000 197.500000000000 1.5
    1905 74 197.500000000000 1.5
    1906 74 197 1.5

    first column is node numbers, second column is x-coord, third column is y-coord and 4th column is z coord. The data is arranged as per the node numbers. There is one more data set which has the mesh relation ship between the nodes and the elements. One element is combination of 8 nodes. it looks like this,

    1 1231 1232 1252 1251 1010 1009 1008 1007
    2 163 110 1232 1231 1006 1005 1009 1010
    3 1230 1231 1251 1250 1004 1010 1007 1003
    4 182 163 1231 1230 1002 1006 1010 1004
    5 1229 1230 1250 1249 1001 1004 1003 1000
    6 183 182 1230 1229 999 1002 1004 1001
    7 1228 1229 1249 1248 998 1001 1000 1019
    8 184 183 1229 1228 1018 999 1001 998

    First column is element number, second to ninths columns are node numbers. First four make one face, last four makes one face.
    Let me know if you need for info.
    Thanks for helping me out.

    Thanks
    Nitesh

  14. dhull replied on :

    @NiTesh

    I think you will want the face vertice representation of PATCH or maybe the data can be massaged into TRIMESH

    doug

  15. Nitesh replied on :

    Hi Doug,

    Thank You very much, PATCH worked for me! It requires the input as I got here. I am getting kind of greedy here, I have same kind of deformation data also for the nodes. Actually, I have mesh data for two meshes, One is fine mesh and one is coarse mesh. The shape is same for both the meshes, the difference is only the number of elements and nodes. I have Deformation data for x,y, and z coordinates for fine mesh. I have to do interpolation and find the deformation data for coarse mesh. Again the problem in using interp1, interp2 and interp3 is the same. The data I have is not in the same format these functions need. Is there any function like PATCH for initerpolation which I can use?

    This will help me alot in dealing with this problem.
    Thanking You

    NItesh

  16. dhull replied on :

    @nitesh,

    I do not understand the question. Please send more details and simple examples via e-mail.

    Doug

  17. Shashikiran replied on :

    Hi,
    Here is my problem.
    x,y are 2 vectors..say of length 400.
    z is a 400×400 matrix generated using x and y vectors….i.e. z(i,j) is calculated based on x(i) and y(j).
    now when i plot mesh(x,y,z),the wireframe is too dark….how can i increase the spacing between the wires….without decreasing x and y vector sizes.
    Shashikiran

  18. dhull replied on :

    @Shashikiran

    http://blogs.mathworks.com/videos/2008/08/13/matlab-basics-setting-edge-color-for-large-surface-plots/

    Try this.

    Doug

  19. Brandy Logan replied on :

    Hi Doug,
    I have non-uniform scalar data, X, Y, Z, velocity. I would like to use slice or contourslice to look at planes of data, but I can’t figure out how to get the velocity data into the right format to plot. The error says velocity must be a 3D array

    Example Data:
    0.0 0 0 13.4
    0.5 -1 -1 13.6
    0.5 -1 0 13.9
    0.5 -1 1 13.8
    0.5 0 -1 14.1
    0.5 0 0 14.2
    0.5 0 1 13.7
    0.5 1 -1 13.7
    0.5 1 0 14.2
    0.5 1 1 14.1
    1 -4 -6 24.1
    1 -4 -4 21.0
    1 -4 -2 17.4
    1 -4 0 15.7
    1 -4 2 15.4
    1 -4 4 17.0
    1 -4 6 20.4
    1 -2 6 16.1
    1 -2 4 13.9
    1 -2 2 14.0
    1 -2 0 14.3
    1 -2 -2 14.7
    1 -2 -4 16.6
    1 -2 -6 21.1
    1 0 -6 20.1
    1 0 -4 15.5
    1 0 -2 14.6
    1 0 0 14.5
    1 0 2 14.4
    1 0 4 13.8
    1 0 6 15.1
    1 2 6 17.1
    1 2 4 14.6
    1 2 2 14.2
    1 2 0 14.4
    1 2 -2 14.6
    1 2 -4 17.1

    I can use meshgrid to get a grid for X and Y and griddata to interpolate the Z, but what about velocity?

  20. dhull replied on :

    @Brandy,

    Try interpn

    Doug

  21. Thibaud replied on :

    Hi Doug,

    I have values of a function on a irregular X,Y grid and I would interpolate it in order to find isocurves where the function is equals to 0.
    I used your code but I had an error which says that sample data points should be collinear. I don’t know how to handle this problem.

    Do you have an idea ?

    Thanks for helping me out.

    Regards,
    Thibaud

  22. dhull replied on :

    @Thibaud,

    Please post simple code for this.

    Doug

  23. Thibaud replied on :

    Thanks Doug for your answer.

    I spent lot of time to find an other way to do it.
    Here is my code :

    nx = 5000; % Number of x steps
    ny = 5000; % Number of y steps
    n = 100; % Time step
    
    x1 = Wzx(:,1); % X-coordinate nodes'
    y1 = Wzx(:,2); % Y-coordinate nodes'
    z1 = Wzx(:,n); % Wzx values a t=n*dt
    
    % X,Y for regular mesh
    xlin = linspace(0,8,nx);
    ylin = linspace(0,3.2,nx);
    
    F = TriScatteredInterp(x1,y1,z1); % Interpolant
    
    z = zeros(nx,ny); % Matrix declaration
    
    % Matrix's filling
    for i=1:nx-1
        for j=1:ny-1
           % For each regular coordinate i,j we evaluate Wzx using the
           % interpolant
            z(i,j)= F(xlin(i),ylin(j));
        end
    end 
    
    % Compute the contour matrix for isoline 0
    C = contourc(z,[0 0]);
    

    What I’m trying to do is to obtain the coordinates (x,y) of the isoline Wzx(x,y) = 0.
    Thus, I interpolate my data on a regular mesh in order to use contourc function which enables me to find 0 isoline.

    But my results are not good.
    Does my code sound sensible ?

    Thank you,
    Thibaud

  24. dhull replied on :

    @Thibaud,

    How are your results ‘not good’?

    Have you done a surface plot of xlin, ylin, z overlayed over a scatterplot of x1,y1,z1? Do they seem reasonable? Is it the interpolation that is bad?

    Doug

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


MathWorks

Doug Hull is a proud MathWorker who is on a mission to help you with MATLAB.

Doug's picture

These postings are the author's and don't necessarily represent the opinions of The MathWorks.