Get ratio from 2 files in gnuplot
Asked Answered
C

4

13

I have 2 dat files:

a.dat
#Xs
100   25
200   56
300   75
400   67


b.dat
#Xs
100   65
200   89
300   102
400   167

I want to draw a graph in the gnuplot where the yy values are a ratio between the values of a.dat and b.dat respectively. e.g., 25/65, 56/89, 75/102, and 67/167.

How I do this? I only know make a plot like this, and not with the ratio.

plot "a.dat" using 1:2 with linespoints notitle
     "b.dat" using 1:2 with linespoints notitle
Contortion answered 19/11, 2013 at 10:58 Comment(0)
V
18

You cannot combine the data from two different files in a single using statement. You must combine the two files with an external tool.

The easiest way is to use paste:

plot '< paste a.dat b.dat' using 1:($2/$4) with linespoints

For a platform-independent solution you could use e.g. the following python script, which in this case does the same:

"""paste.py: merge lines of two files."""
import sys

if (len(sys.argv) < 3):
    raise RuntimeError('Need two files')

with open(sys.argv[1]) as f1:
    with open(sys.argv[2]) as f2:
        for line in zip(f1, f2):
            print line[0].strip()+' '+line[1],

And then call

plot '< python paste.py a.dat b.dat' using 1:($2/$4) w lp

(see also Gnuplot: plotting the maximum of two files)

Variegate answered 19/11, 2013 at 11:21 Comment(4)
I love numpy as much as the next guy, but I think that it's use here is a bit excessive. You could accomplish the same thing with "vanilla" python by ziping 2 file objects.Vaticide
@Vaticide You are right, I added a possible implementation of paste.py with 'vanilla' python. Feel free to correct it! It also has the advantage, that it is much more flexible then the numpy implementation since it doesn't parse the files before merging them.Variegate
+1 for a portable solution. Since python 2.7 and 3.1, it is possible to combine with statements, so you can do with open(sys.argv[1]) as f1, open(sys.argv[2]) as f2: and reduce the level of nesting.Interlocution
Following a duplicate of this question, I post another answer. I think it's interesting to point out the join command, not that easily portable but allowing to merge files on column values.Bibliomania
B
5

The short answer is that... you cannot. Gnuplot processes one file at a time.

The work-around is to use an external tool, e.g. using the shell if you have a unix-like, or gnuplot.

join file1 file2 > merged_file will allow you to merge your files quite easily if the first column is identical in both files. Options allow to join on other columns and manage data missing in either file.

In case there is no common column but hte line number is relevant, paste will do.

In case interpolation is required, because the grids in the two files differ, you have to code this. I have a command-line utility that I distribute as free open-source software and can help: datamerge.

Bibliomania answered 9/6, 2015 at 11:38 Comment(0)
A
0

There is a trick if the two datasets don't fit (different sampling in x), but you have a good mathematical model for at least one of them:

fit f2(x) data2 us 1:2 via ...
set table $corr
plot data1 using 2:(f2($1))
unset table

plot $corr using 1:2

This is of course nonsense if both datasets have the same set of independent variables, because you can simply combine them (see other answers).

Antihero answered 9/6, 2015 at 22:49 Comment(0)
O
0

Just for fun, there is a gnuplot-only and platform-independent solution.

For sure, the command plot '< paste a.dat b.dat' using 1:($2/$4)' from Christoph's answer is unbeatable short (and certainly efficient) in case you are working under Linux or installed the CoreUtils from GnuWin under Windows.

The solution below takes the detour via two long strings. This should work fine unless there is a length limit of strings in gnuplot. I tested only until 100'000 data lines, which will take quite a few minutes. The assumption is that the two files have equal lines with identical x-values. For gnuplot>=5.0 you could write into a datablock instead of a file on disk and do further optimizations.

Script: (works with gnuplot>=4.6.0, March 2012)

### get ratio of numbers from different files
reset 

FILE1 = "SO20069641a.dat"
FILE2 = "SO20069641b.dat"
FILE  = "SO20069641.dat"

# create some random test data
set samples 100
set table FILE1
    plot '+' u (int($0+1)*100):(int(rand(0)*100)+1)
set table FILE2
    plot '+' u (int($0+1)*100):(int(rand(0)*100)+1)
unset table

a = ''
b = ''
stats FILE1 u (a=a.' '.strcol(1).' '.strcol(2)) nooutput
stats FILE2 u (b=b.' '.strcol(1).' '.strcol(2)) nooutput

set table "SO20069641.dat"
    set samples words(a)/2
    splot '+' u (n=2*(int($0+1)),real(word(a,n-1))):(real(word(a,n))):(real(word(b,n)))
unset table

plot FILE u 1:($2/$3) w impulses
### end of script

Result:

enter image description here

Oppugnant answered 3/8, 2022 at 15:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.