Search code examples
gnuplot

Plotting surface with gnuplot, but I only have a Z-data datafile


I have a data file containing z values (m x n = 2068 x 100), but I fail to find a way to make a surface plot in gnuplot out of that. In MATLAB the command is straight forward: just surf(M).

The values correspond to readouts over time from a spectrometer, i.e.

wavelength scan1   scan2     scan3     scan4
772.7    3.9609    3.9623    3.9593    3.9643
772.8    2.4688    2.4749    2.4669    2.4689
772.9    2.7233    2.7250    2.7240    2.7270

I understand that gnuplot expects the data to be presented in x,y,z fashion, but my data does not provide that. I'm sorry that I can find no other way to describe what I'm after... Essentially: the x values are in the first row, but the y values should be the index of the column if that makes sense.

Any help would be much appreciated.


Solution

  • Your data format is halfway between the two formats gnuplot knows about. splot $DATA matrix treats all values as z values (no x or y specified). splot $DATA matrix nonuniform expects the first column to contain y values and the first row to contain x values. You have one column of coordinate data but not one row of coordinate data.

    It looks like your x values are evenly spaced, so it would produce a valid surface to ignore them:

    splot 'matrix.dat' matrix skip 1 every 1::1
    
    • matrix tells gnuplot it is an array of z values
    • skip 1 tells it to skip the first row, which contains labels rather than z
    • every 1::1 tells it to read every column starting with column 1 (i.e. skip column 0)

    enter image description here

    However a much better approach is to draw a separate line for each scan rather than trying to treat it as a surface:

    set ylabel "Scan" offset 5
    set xlabel "Wavelength" offset 0,-2
    set xtics .1 offset 0,-1
    unset ytics
    unset ztics
    splot for [col=2:*] 'matrix.dat' using 1:(col):col title columnhead
    

    enter image description here