Search code examples
gnuplotfence-plots

Gnuplot: fence plot from data


I'm trying to figure out how to do fence plots in gnuplot, but I'm having a hard time understanding what's going on in the examples I find on the internet.

I have a (varying) number of data sets from different points in time in my simulation, in a datafile organized as a matrix of values1:

t1    x11    y11   // indices here indicate that (x1,y1) are a data point which
t1    x21    y21   // I'd plot on a regular 2D plot for this timestep, with the
...                // additional index noting which time step the values are for.
t1    xN1    yN1   
[blank line]
t2    x12    y12
t2    x22    y22
...
t2    xN2    yN2
[etc...]
tM    xNM    yNM

I want to plot this with one fence for each time value. I can plot do simply splot 'data.txt' and get something which is quite similar to what I want - + markers along the "top edges" of the fences, with time on x axis, x-data on y axis and y-data on z axis. However, if I add something like w lines to the splot command I just get a surface with all the data series connected.

I've tried to adapt the examples from the demo script collection (about halfway down), but they both rely on a dummy variable, and I can't figure out how to combine that with my data series. I've found some other exampels as well, but they are all quite elaborate and I don't understand what they do at all.

What is a good way to create fence plots from data using gnuplot?


1 If it's necessary, it is possible to change this - I am in control of the code that generates the data. It's a hassle, though...


Solution

  • This does require a bit of a change to the data unfortunately. The change is pretty minor though and could probably be handled with a simple awk1,2 script:

    Here's a copy/paste of my interactive gnuplot session:

    gnuplot> !cat test.dat
    1 2 3
    1 2 0
    
    1 3 4
    1 3 0
    
    1 4 5
    1 4 0
    
    
    2 2 3
    2 2 0
    
    2 3 4
    2 3 0
    
    2 4 5
    2 4 0
    
    
    3 2 3
    3 2 0
    
    3 3 4
    3 3 0
    
    3 4 5
    3 4 0
    !
    gnuplot> splot 'test.dat' u 1:2:3 w lines
    

    The thing to note here is that there are 2 blank lines between "fences" and each x,y data point appears twice with a blank line afterward. The second time it appears, the z-coordinate is 0.

    To get each fence to have a different color:

    gnuplot> splot for [i=0:3] 'test.dat' index i u 1:2:3 w lines
    

    The awk script can even be done inline:

    splot "< awk {...} datafile"
    

    But that can get a little tricky with quoting (to include a single quote in a single quoted string, you double it) ...

    AWKCMD='awk ''{if(!NF){print ""}else if(index($0,"#")!=1){printf "%s %s %s\n%s %s 0\n\n", $1,$2,$3,$1,$2}}'' '
    splot '<'.AWKCMD.'datafile.dat' u 1:2:3 w lines
    

    As far as efficiency is concerned, I'm believe that the iteration I used above will call the awk command for each time it iterates. The workaround here is to pull the color from the index number:

    splot '<'.AWKCMD.' test.dat' u 1:2:3:(column(-2)) w l lc variable
    

    I believe that this will only do the awk command once as desired so with only a million entries it should still respond relatively quickly.


    1awk '{if(!NF){print ""}else{printf "%s %s %s\n%s %s 0\n\n", $1,$2,$3,$1,$2}}' test.dat

    2awk '{if(!NF){print ""}else if(index($0,"#")!=1){printf "%s %s %s\n%s %s 0\n\n", $1,$2,$3,$1,$2}}' test.dat (version which ignores comments)