views:

2564

answers:

3

I have seen 3d surface plots of data before but i do not know what software i could use to make it.

I have 3 series of data (X, Y, Z) basically i want each of the rows on the table to be a point in 3d space, all joined as a mesh. The data is currently csv, but i can change the format, as it is data i generated myself.

Can anyone help

+1  A: 

Have you looked at using vtk? If you have Matlab then you should be able to use plot3d or surf with meshgrid and griddata to generate 3D surface plots or patch as suggested by Mr. Fooz.

Azim
This looks too complicated for me, I have access to matlab but i have no experience with it. nlucaroni's script seems like it will to everything i need if i play with it a bit.Thanks :D
Ben Page
granted vtk may be too powerful for what you need. Matlab/Scilab/Octave are all fairly straight forward.
Azim
A: 

gnuplot or scilab

Below is a script for SciLab that I wrote awhile back. It reads in three columns separated by tabs. You can easily change this to fit your needs, pretty self-explanatory. Here is a quick guide to reading/writing in scilab and the one I reference below is here:

function plot_from_file(datafile)
//
// Make a simple x-y-z plot based on values read from a datafile.
// We assume that the datafile has three columns of floating-point
// values seperated by tabs.

  // set verbose = 1 to see lots of diagnostics
  verbose = 1;

  // open the datafile (quit if we can't)
  fid = mopen(datafile, 'r');
  if (fid == -1) 
    error('cannot open datafile');
  end

  // loop over all lines in the file, reading them one at a time
  num_lines = 0;
  while (true)

    // try to read the line ...
    [num_read, val(1), val(2), val(3)] = mfscanf(fid, "%f\t%f\t%f");
    if (num_read <= 0)
      break
    end
    if (verbose > 0)
      fprintf(1, 'num_lines %3d  num_read %4d \n', num_lines, num_read);
    end
    if (num_read ~= 3) 
      error('didn''t read three points');
    end

    // okay, that line contained valid data.  Store in arrays
    num_lines = num_lines + 1;
    x_array(num_lines) = val(1);
    y_array(num_lines) = val(2);
    z_array(num_lines) = val(3);
  end

  // now, make the plot
  plot3d2(x_array, y_array, z_array);
  // close the datafile
  mclose(fid);

endfunction
nlucaroni
wait a minute... when I get home I'll check the script. why didn't I use done_yet anywhere??
nlucaroni
This looks like it would work for me, but you say its not complete, it looks like it will be an infinite loop. Would it be easy me to use scilab?
Ben Page
seems this will only generate a cloud of points. sounded like you wanted a surface.
Azim
Ok, no. there is a break. But it used to be that instead of the break line, it would set done_yet to 0. to Azim: then he'd have to interpolate the data, which is different then what he asked.
nlucaroni
To @nlucaroni I guess I was focusing on the "joined as a mesh" part of the question. Then I agree the OP would need to have the data formatted as Mr. Fooz points out.
Azim
+5  A: 

If your x & y points topologically lie on a grid, then you can use MESH. They don't need to have even spacing; they just need to be organized so that x(r:r+1,c:c+1) and y(r:r+1,c:c+1) define a quadrilateral on your mesh, for each row r and column c.

If your data do not lie on a grid, but you know what the faces should be, look at the PATCH function.

If you only have points and you don't know anything about the surface, you need to first solve the surface reconstruction problem. I've used cocone; there are other good packages there too. Once you have the reconstructed surface, then you can use PATCH to display it.

Mr Fooz
+1 for highlighting the correct issues if the OP wants to generate surface instead of cloud of points.
Azim