7

I have data generated in a simulation. The generated data file looks something like this:

1990/01/01 99
1990/01/02 92.7
1990/01/03 100.3
1990/01/04 44.2
1990/01/05 71.23
...
2100/01/01 98.25

I can create a chart (trivially), by simply issuing the (long versioned) command:

plot "simulation.dat" using 1:2 with line

I want to add a third column which will add arrow information. The encoding for the third column would be as follows:

  • 0 => no arrow to be drawn for that x axis value
  • 1 => an UPWARD pointing arrow to be drawn for the x axis value
  • 2 => a DOWNWARD arrow to be drawn for the x axis value

I am just starting to learn gnuplot, and will appreciate help in how I can use gnuplot to create the arrows on the first plot?

oompahloompah
  • 9,087
  • 19
  • 62
  • 90
  • Hi, I think I got your gnuplot question working (on linux at least) I updated my answer. – Tom Jan 27 '11 at 15:40

3 Answers3

4

I dont think there is an automatic way to create all your arrows at the same time based on the third column. You will have to execute the following for each arrow that you want:

set arrow xval1,yval1 to xval2,yval2

You can also use relative arrows

set arrow xval1,yval1 rto 1,0

This will draw a horizontal arrow from xval1,yval1 to (xval1+1),yval1

There are plenty of options associated with the set arrow command:

chutz
  • 2,256
  • 2
  • 25
  • 38
Martin
  • 1,084
  • 9
  • 15
3

If you didn't want the arrow head then you might try the impulses style (with impulses rather than with lines) (If you still want the lines on top then you can plot twice).

If you really want the arrow heads then the following might help: It uses a for loop (or sorts) to add vertical arrows to a plot.

Gnuplot script, for loop within or adding to existing plot

Specifically:

create a file simloop.gp which looks like the following:

count  = count+1
#save the count to count.gp
system 'echo '.count.' > count.gp'
#load the simloop shell
system "./simloop.sh"

#draw the arrow
load 'draw_arrow.gp'

if(count<max) reread

Then create a simloop.sh file that looks something like so

#!/bin/bash

#read the count
count=$(awk -F, '{print $1}' count.gp)
#read the file
xcoord=$(awk -v count=$count -F, 'BEGIN{FS=" ";}{ if(NR==count) print $1}' simulation.dat)
ycoord=$(awk -v count=$count -F, 'BEGIN{FS=" "}{ if(NR==count) print $2}' simulation.dat)
dir=$(awk -v count=$count -F, 'BEGIN{FS=" "}{ if(NR==count) print $3}' simulation.dat)

#choose the direction of the arrow
if [ \"$dir\" == \"0\" ]; then
    echo '' > draw_arrow.gp
fi

if [ \"$dir\" == \"1\" ]; then
  echo 'set arrow from ' $xcoord' ,0 to '$xcoord','$ycoord' head' > draw_arrow.gp
fi

if [ \"$dir\" == \"2\" ]; then
 echo 'set arrow from '$xcoord',0 to '$xcoord','$ycoord' backhead' > draw_arrow.gp
fi

Then create a simulation.gp file that looks something like so:

count = 0;
max = 5;
load "simloop.gp"
set yrange[0:*]
plot "simulation.dat" u 1:2 w l

Make sure the shell file has executable permissions (chmod +wrx simloop.sh), load up gnuplot and type

load "./simulation.gp"

This worked for me with the data file

1  99   0
2  92.7 1
3 100.3 2
4 44.2  0
5 71.23 1

(For testing I got rid of the time formatting You should be able to put it back without too much trouble.)

Then I got this graph: enter image description here

Which I think is more or less what you want.

Community
  • 1
  • 1
Tom
  • 5,219
  • 2
  • 29
  • 45
  • Nicely done, I always call gnuplot from other code so I did not realize that such scriptfiles are not too complicated. However, I do think that if you generate the inputfile yourself it might be most easy to plot the arrows at the same time in your code. If not this solution is perfect! – Martin Jan 27 '11 at 16:46
  • thanks for the input. However, your approach is a bit too complicated for me (I don't grok sed and awk too well ;) – oompahloompah Jan 30 '11 at 02:55
2

Although the question is quite old, here is my answer.

One can use the vectors plotting style, which can use variable arrowstyles based on a column's value:

set style arrow 1 backhead
set style arrow 2 head
set yrange[0:*]
set xdata time
set timefmt "%Y/%m/%d"
plot "simulation.dat" using 1:2 with line,\
     "" using 1:2:(0):(-$2):($3 == 0 ? 1/0 : $3) with vectors arrowstyle variable

It the value of a column is 1/0, the point is considered as undefined and is skipped.

Christoph
  • 47,569
  • 8
  • 87
  • 187