1
votes

I have data files "y.csv" which contains several runs (data sets) of an experiment in columns that I want to simultaneously fit to a single function. It should work like plot for [i=2:*] "y.csv" using 1:i to automatically accomodate however many columns are in the file. Here is a short example data file:-

,B,C,D,E,F,G,H
01,,,,,,,
02,0.2200,0.2200,0.2080,0.2170,0.1530,,
03,0.2720,0.3230,0.2530,0.2380,0.2620,,
04,0.3900,0.3790,0.3770,0.3760,0.3500,,
05,0.5520,0.5600,0.5450,0.4830,0.4870,,
06,0.6640,0.6300,0.6830,0.6030,0.6520,,
07,0.6440,0.6900,0.6360,0.5960,0.6520,,
08,0.6030,0.6470,0.6190,0.6300,0.6280,,
09,0.5450,0.5890,0.5860,0.6830,0.5540,,
10,0.6370,0.6430,0.5800,0.5270,0.6180,,
11,0.6400,0.5600,0.7190,0.6780,0.7420,,
12,,,,,,,

I can automatically plot each of these columns, overlooking column headers, etc with:-

  set datafile separator ","
  set datafile columnheaders
  set key autotitle columnheader
  set key top left
  set key title "Run"
  set xrange [1:12]
  set xlabel "Dilution (Proportional to log([]) )"
  set ylabel "Response"
  plot for [i=2:*] "y.csv"  using 1:i  with linespoints

Plot of all columns

I can set up a function to fit with the following:-

  sig(x) = 1 / (1+exp(-x))       ; # Appears stable enough in gnuplot
  A = 0.6                        ; # Sigmoid Amplitude
  B = 0.2                        ; # Sigmoid offset
  C = 6                          ; # Center shift on displayed X axis
  K = 1                          ; # Shape factor
  ssig(x) = B + A*sig(K*(x-C))   ; # Fit to this

And, I can fit to the first data column with:-

 fit ssig(x)  "y.csv"  using 1:2  via A,B,C,K

But I can't work out the syntax of how to automatically do this over all the columns like I can for plotting. I was expecting something like

fit [1:-1:i=2:*]  ssig(x)  "y.csv"  using 1:i  via A,B,C,K

would iterate over the columns. I just don't understand the multi-branch syntax, and guess I am missing some simple concept. Many thanks

1
Your question is a bit ambiguous, may I ask you to clarify? Do you want to perform an independent fit over all data sets, i.e. do you want to obtain something like A_1, B_1, C_1, K_1 for the first set, A_2, B_2, C_2, K_2 for the second and so on? Or do you want to perform a multi-branch fit, where some of the fit parameters are the same for all data sets (e.g. A and K might have some global meaning), while others have individual values for each data set (e.g. B_1, B_2, B_3...)? - Eldrad
I think I want a multi-branch fit. A single set of A, B, C, K to best fit all the runs of the experiment, to the function. - mjp
I have the impression that you are using the term multi-branch fit in a wrong way. It would mean that you have two (or more) functions, that share some (but not all!) common parameters. For example you might fit f_1(x) = B_1 + A*sig(K*(x-C_1)) to the first data set, f_2(x) = B_2 + A*sig(K*(x-C_2)) to the second one and so on. (Note that the functions depend on the same A and K, but different B's and C's!) But according to your comment you just want to use all data points for one single function – I provided an answer for that. - Eldrad
Many thanks @Eldrad. I think I became mislead down the multi-branch path while reading the GNUPlot manual. It is rather a short section, and was beginning to think I missed something elsewhere, hence this post. I could not see how tables might help, and was expecting something more independent like I had used in the past. I hope this page helps others. - mjp

1 Answers

1
votes

Based on your comment you are actually not searching for a multi-branch fit, but you want to merge all columns into one single data set and perform a fit using all data points at the same time. This can be achieved quite easily by reshaping the data file into a datablock first:

set datafile separator ","
set table $FITDATA
plot for [i=2:*] "y.csv" u 1:i
unset table
unset datafile separator
sig(x) = 1 / (1+exp(-x))       ; # Appears stable enough in gnuplot
A = 0.6                        ; # Sigmoid Amplitude
B = 0.2                        ; # Sigmoid offset
C = 6                          ; # Center shift on displayed X axis
K = 1                          ; # Shape factor
ssig(x) = B + A*sig(K*(x-C))   ; # Fit to this
set fit errorvariables
fit ssig(x) $FITDATA u 1:2 via A,B,C,K

In the datablock the columns are separated by tabs, not comma, therefore one has to revert the datafile separator to default while fitting, and change it back again for plotting. Maybe someone else has a cleaner solution for this. set fit errorvariables saves the fit errors, so that they can be used for the plot title later.

set datafile separator ","
set datafile columnheaders
set key autotitle columnheader
set key top left
set key title "Run"
set xrange [1:12]
set xlabel "Dilution (Proportional to log([]) )"
set ylabel "Response"

plot for [i=2:*] "y.csv" u 1:i w lp, \
ssig(x) lc black lw 3 t "fit", \
keyentry t sprintf("A = %.3f ± %.3f", A, A_err), \
keyentry t sprintf("B = %.3f ± %.3f", B, B_err), \
keyentry t sprintf("C = %.3f ± %.3f", C, C_err), \
keyentry t sprintf("K = %.3f ± %.3f", K, K_err)

enter image description here