0

I have two files "f.txt" and "g.txt". The data in both files are arranged in two columns, the column separator being just a few whitespaces. The first column stand for the independent variable "x" and the second column for f(x) (or g(x)). It is easy to plot the function y= f(x) and y = g(x), but is there a simple way to plot f(x) against g(x)? Of course, using bash, I could create an "intermediary" file with first column g(x) and second column f(x) and then plotting normally this file. Is there however a way to do this without actually creating this file?

Patrick.B
  • 135
  • 4
  • 1
    You can combine the files and feed the result directly to gnuplot without creating an intermediate file https://stackoverflow.com/a/20070138/2604213 – Christoph May 01 '20 at 14:29

1 Answers1

1

Your question was partly contradictory. It looked like you have two files with two columns each, i.e. x,f(x) and x,g(x). I assume that the number of rows and the values of x are identical. And you "simply" want to plot f(x) versus g(x). But this is not the same as plotting f(g(x)) (as in your original question). In the latter case you probably would need interpolation.

@Christoph already pointed to a simple solution merging to files with awk. In case you don't have or don't want to use awk, here is a somewhat cumbersome gnuplot-only solution.

  1. load files 1:1 to datablock (see gnuplot: load datafile 1:1 into datablock, although, still not fully answered)
  2. remove the end of line character(s). This depends on the operating system. For Windows I have to put \r as end of line character (for some reason not \r\n). Currently, I cannot test Linux and MacOS.
  3. print/append lines to a new datablock

Data:

f.txt

A,B
1,3
2,6
3,5

g.txt

A,C
1,8
2,4
3,7

Code:

### merge two files (merging their lines)
# assumption: equal number of lines in each file
reset session

# load files 1:1 to datablocks
FILE1 = 'f.txt'
if (GPVAL_SYSNAME[:7] eq "Windows") { load '< echo   $Data1 ^<^<EOD  & type "'.FILE1.'"' }
else                                { load '< echo "\$Data1  << EOD" &  cat "'.FILE1.'"' } # Linux & MacOS
FILE2 = 'g.txt'
if (GPVAL_SYSNAME[:7] eq "Windows") { load '< echo   $Data2 ^<^<EOD  & type "'.FILE2.'"' }
else                                { load '< echo "\$Data2  << EOD" &  cat "'.FILE2.'"' } # Linux & MacOS

mySeparator = ","
myEOLc = sprintf("\r",0)     # End of Line character Linux: "\n", Windows: "\r\n", Mac: "\r"
# function for removing EOL character(s) from a string
RemoveEOLc(s) = s[strlen(s)-strlen(myEOLc)+1:strlen(s)] eq myEOLc ?  s[1:strlen(s)-strlen(myEOLc)] : s

set print $Data3
    do for [i=1:|$Data1|] {
        print sprintf("%s%s%s", RemoveEOLc($Data1[i]), mySeparator, RemoveEOLc($Data2[i]))
    }
set print

print $Data3
### end of code

Result:

A,B,A,C
1,3,1,8
2,6,2,4
3,5,3,7

An then plot your data as you like...

Addition:

If your files have whitespace as column separator you can use word("string",n) to extract a "column" from $Data[i] (see help word). Then you need to change the lines:

mySeparator = " "

and

print sprintf("%s%s%s", word(RemoveEOLc($Data1[i]),2), mySeparator, word(RemoveEOLc($Data2[i]),2))

Result:

B C
3 8
6 4
5 7
theozh
  • 22,244
  • 5
  • 28
  • 72
  • Thank you for this! I was indeed not precise in what I wanted, but you correctly understood my question. Sorry for being very picky, but would it be possible for the result to only have the rows B and C, i.e. without the (duplicate) rows A? – Patrick.B May 04 '20 at 16:14
  • only B and C would also be possible, but a bit more cumbersome in gnuplot. What is your column separator? Whitespace would be easier than other characters like `,` or `;` etc... – theozh May 04 '20 at 16:18
  • You may assume that my column separator are (a couple of) whitespaces. – Patrick.B May 04 '20 at 16:26