astha
astha

Reputation: 613

How to merge all plots in one window in gnuplot

I know similar question are asked and answered multiple times in SO. Here I have something unique that includes the fitting for each plot. I am using

f(x) = (a0 + a1/x)
fit f(x) 'test.data' using 1:2 via a0,a1
plot 'test.data' using 1:2 w points pt 1 t  ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

f(x) = (a0 + a1/x)
fit f(x) 'test.data' using 1:3 via a0,a1
plot 'test.data' using 1:3 w points pt 1 t  ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

here I am skipping other plot commands to keep the query short.

f(x) = (a0 + a1/x)
fit f(x) 'test.data' using 1:8 via a0,a1
plot 'test.data' using 1:8 w points pt 1  ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

f(x) = (a0 + a1/x)
fit f(x) 'test.data' using 1:9 via a0,a1
plot 'test.data' using 1:9 w points pt 1 t   ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

Using the above plots, I am getting one box for each plot.

How I can merge all plots in a single window?

The data files is having 9 columns (1st colum will be x-axis while others are y-axos) and inserting plot commands for each plot makes the gnuplot script too long. Is there any workaround so that I do not need to type p"plot each time and the job can be done by some loop?

I tried to manage all plots in a single box using

plot for [i=1:9] 'test.data' using (i):i notitle with boxplot lt -1, \
f(x) = (a0 + a1/x)
fit f(x) 'test.data'for [i=1:9] using (i):i via a0,a1 
plot 'test.data' for [i=1:9] using (i):i w points pt 1 t ,  f(x) t sprintf("K_{fit} = a_0 +  a_1/T", a0)

but I am getting below error

fit f(x) 'test.data'for [i=1:9] using (i):i via a0,a1 
                        ^
"test.gnu", line 23: Need via and either parameter list or file

Below is my test.data file

100.0 0.45564E+02 0.20558E+02   0.53903E+02 0.24899E+02 0.56334E+02 0.26169E+02 0.58482E+02 0.27273E+02
200.0 0.17118E+02 0.81681E+01   0.18147E+02 0.86680E+01 0.18397E+02 0.87831E+01 0.18598E+02 0.88736E+01
300.0 0.10908E+02 0.53456E+01   0.11307E+02 0.55301E+01 0.11398E+02 0.55703E+01 0.11470E+02 0.56013E+01
400.0 0.81160E+01 0.40313E+01   0.83328E+01 0.41288E+01 0.83808E+01 0.41496E+01 0.84181E+01 0.41655E+01
500.0 0.64937E+01 0.32506E+01   0.66311E+01 0.33115E+01 0.66611E+01 0.33243E+01 0.66841E+01 0.33340E+01
600.0 0.54231E+01 0.27282E+01   0.55185E+01 0.27700E+01 0.55390E+01 0.27787E+01 0.55547E+01 0.27853E+01
700.0 0.46602E+01 0.23525E+01   0.47305E+01 0.23830E+01 0.47455E+01 0.23894E+01 0.47569E+01 0.23942E+01
800.0 0.40878E+01 0.20687E+01   0.41419E+01 0.20920E+01 0.41533E+01 0.20968E+01 0.41620E+01 0.21005E+01
900.0 0.36419E+01 0.18465E+01   0.36847E+01 0.18649E+01 0.36937E+01 0.18687E+01 0.37006E+01 0.18716E+01
1000.0 0.32843E+01 0.16677E+01  0.33192E+01 0.16826E+01 0.33264E+01 0.16857E+01 0.33320E+01 0.16880E+01

Upvotes: 1

Views: 450

Answers (1)

theozh
theozh

Reputation: 26200

If you check help fit you won't find that gnuplot can fit in a loop as in a plot loop. But you can fit several data columns in a do for loop, check help do. And you can store the fit parameters in arrays for plotting them later in a plot for loop. I hope you can figure out how the example code below works.

Code:

### fit multiple columns in a loop
reset session

f(x) = a0 + a1/x

# arrays for fit parameters
array arr0[8]
array arr1[8]

# create some random test data
do for [i=1:8] {
    arr0[i] = int(rand(0)*50)+5
    arr1[i] = int(rand(0)*10)+5
}
set print $Data
do for [x=10:50] {
    line = sprintf("%g",x/100.)
    do for [i=1:8] {
        a0 = arr0[i]
        a1 = arr1[i]
        line = line.sprintf(" %.3f",f(x/100.)+10*i)
    }
    print line
}
set print

# fit columns in a loop and put fit values into array
do for [i=1:8] {
    fit f(x) $Data u 1:i+1 via a0,a1
    arr0[i] = a0
    arr1[i] = a1
} 

set key Left
plot for [i=1:8] $Data u 1:i+1 ti sprintf("%d: a0=%.1f, a1=%.1f",i,arr0[i],arr1[i]), \
     for [i=1:8] tmp=(a0=arr0[i],a1=arr1[i]) f(x) w l lc rgb "red" not
     
### end of code

Result:

enter image description here

Addition (with OP's data)

Code:

### fit multiple columns in a loop
reset session

f(x) = a0 + a1/x

# arrays for fit parameters
array arr0[8]
array arr1[8]

$Data <<EOD
100.0 0.45564E+02 0.20558E+02   0.53903E+02 0.24899E+02 0.56334E+02 0.26169E+02 0.58482E+02 0.27273E+02
200.0 0.17118E+02 0.81681E+01   0.18147E+02 0.86680E+01 0.18397E+02 0.87831E+01 0.18598E+02 0.88736E+01
300.0 0.10908E+02 0.53456E+01   0.11307E+02 0.55301E+01 0.11398E+02 0.55703E+01 0.11470E+02 0.56013E+01
400.0 0.81160E+01 0.40313E+01   0.83328E+01 0.41288E+01 0.83808E+01 0.41496E+01 0.84181E+01 0.41655E+01
500.0 0.64937E+01 0.32506E+01   0.66311E+01 0.33115E+01 0.66611E+01 0.33243E+01 0.66841E+01 0.33340E+01
600.0 0.54231E+01 0.27282E+01   0.55185E+01 0.27700E+01 0.55390E+01 0.27787E+01 0.55547E+01 0.27853E+01
700.0 0.46602E+01 0.23525E+01   0.47305E+01 0.23830E+01 0.47455E+01 0.23894E+01 0.47569E+01 0.23942E+01
800.0 0.40878E+01 0.20687E+01   0.41419E+01 0.20920E+01 0.41533E+01 0.20968E+01 0.41620E+01 0.21005E+01
900.0 0.36419E+01 0.18465E+01   0.36847E+01 0.18649E+01 0.36937E+01 0.18687E+01 0.37006E+01 0.18716E+01
1000.0 0.32843E+01 0.16677E+01  0.33192E+01 0.16826E+01 0.33264E+01 0.16857E+01 0.33320E+01 0.16880E+01
EOD

# fit columns in a loop and put fit values into array
set fit nolog
do for [i=1:8] {
    fit f(x) $Data u 1:i+1 via a0,a1
    arr0[i] = a0
    arr1[i] = a1
} 

set key Left
plot for [i=1:8] $Data u 1:i+1 ti sprintf("%d: a0=%.1f, a1=%.1f",i,arr0[i],arr1[i]), \
     for [i=1:8] tmp=(a0=arr0[i],a1=arr1[i]) f(x) w l lc rgb "red" not
     
### end of code

Result:

enter image description here

Addition: (after your comments)

You can also plot the data in a loop. You can simply define functions for the linetype and the dashtype. Dashtype dt 1 is a solid line and dt 2 is a dashed line basically identical to dt "-". Type test in the gnuplot console and you will see the different linestyles.

Maybe also an explanation for the term tmp=(a0=arr0[i],a1=arr1[i]). You can add a definition in the plot command (see help plot), but since we need two definitions a0=arr0[i] and a1=arr1[i] we use serial evaluation (see help operators binary) and assign it to a dummy variable tmp.

Your functions and the plot command would then be:

myLineType(i) = (i-1)/2+1    # Attention: /2 in gnuplot is integer division if `i` is integer!
myDashType(i) = (i-1)%2+1    # % is modulo

plot for [i=1:8] $Data u 1:i+1 w l lw 2 lt myLineType(i) dt myDashType(i) not, \
     for [i=1:8] tmp=(a0=arr0[i],a1=arr1[i]) f(x) w p lt myLineType(i) not

Upvotes: 2

Related Questions