3

I have a data file with 24 lines and 3 columns. How can I plot only the data from specific lines, e.g. 3,7,9,14,18,21? Now I use the following command

plot 'xy.dat' using 0:2:3:xticlabels(1) with boxerrorbars ls 2

which plots all 24 lines.

I tried the every command but couldn't figure out a way that works.

3 Answers 3

3

Untested, but something like this

plot "<(sed -n -e 3p -e 7p -e 9p xy.dat)" using ...

Another option may be to annotate your datafile, if as it seems, it contains multiple datasets. Let's say you created your datafile like this:

1 2 3
2 1 3 # SetA
2 7 3 # SetB
2 2 1 # SetA SetB SetC

Then if you wanted just SetA you would use this sed command in the plot statement

sed -ne '/SetA/s/#.*//p' xy.dat
2 1 3
2 2 1

That says..."in general, don't print anything (-n), but, if you do see a line containing SetA, delete the hash sign and everything after it and print the line".

or if you wanted SetB, you would use

sed -ne '/SetB/s/#.*//p' xy.dat
2 7 3
2 2 1

or if you wanted the whole data file, but stripped of our comments

sed -e 's/#.*//' xy.dat

If you wanted SetB and SetC, use

sed -ne '/Set[BC]/s/#.*//p' xy.dat
2 7 3 
2 2 1
Sign up to request clarification or add additional context in comments.

Comments

2

If the lines you want have something in common that you can evaluate, e.g. the label in column 1 begins with an "a"

 plot dataf using (strcol(1)[1:1] eq "a" ? $0 : NaN):2:xticslabel(1)

you can just skip these lines by letting the using statement return "NaN".

This here is an ugly hack you can use in case the desired line numbers are just arbitrary:

linnum = " 1 3 7 12 16 21 "
plot dataf using (strstrt(linnum," ".int($0)." ") != 0 ? $0 : NaN):2

strstrt(a,b) returns the position of string b in string a, zero if it does not appear. I add the two spaces to make the line numbers unique.

But I would recommend using an external program to preprocess the data in that case, see the other answer.

Comments

1

Yes, there is a solution with every. Since you want to plot with boxerrorbars it can be done in a plot for-loop.

  • no external tools, i.e. gnuplot-only and hence platform-independent
  • no strictly increasing line numbers, but arbitrary sequence of lines possible

Script:

### plot only certain lines appearing in a list
reset session

# create some random test data
set print $Data
do for [i=1:24] {
    print sprintf("line%02d  %g  %g", i, rand(0)*5+1, rand(0)*0.5)
}
set print

myLines   = "3 7 9 14 18 21"
myLine(i) = int(word(myLines,i)-1)

set offsets 0.5,0.5,0,0
set style fill solid 0.3
set boxwidth 0.6
set xtics out
set key noautotitle
set yrange [0:]

plot for [i=1:words(myLines)] $Data u (i):2:3:xtic(1) \
         every ::myLine(i)::myLine(i) w boxerrorbars lc "blue"
### end of script

Result:

enter image description here

1 Comment

Very elegant... nice work!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.