1

This is a followup of my earlier question here: "gnuplot bashshell to plot several curves in one window" which Christoph kindly helped with it. However, I had simplified my question assuming I would be able to advance from there on my own. No need to say, I couldn't! :( what I really want to plot in one fig frame is a set of data files and for each of the data files a curve(exponential function) fitted to it. Unfortunately I'm stuck with gnuplot 4.2 which doesn't allow me to use for loop and iterations. I would greatly appreciate any advice. The following bash cript prints nine curves and their fitted lines on separate files.

#!/bin/bash

for Counter in {1..9}; do
FILE="dataFile"$Counter".data"
gnuplot <<EOF
set xlabel "k"
set ylabel "p(k)"
set term png
set output "${FILE}.png"
title_fexp(a,b) = sprintf('exp(x) = %.2f * e(%.2f)', a, b)
expon(x) = c * exp(-x*d)
fit [10:100] expon(x) '${FILE}' via c,d
plot [1:50] expon(x)t title_fexp(c,d), '${FILE}' 
EOF
done
Community
  • 1
  • 1
PyPhys
  • 129
  • 5
  • 10
  • Do you already have all the fitting parameters ready? Then it's a matter of reading them into gnuplot. If they are in an external file you can read them using an external command. E.g. you have a `temp` file with the text `12345` in it, you can read it to gnuplot using `a=system("awk 'NR == 1 {print $1}' temp")`. – Miguel Oct 03 '14 at 08:15
  • What is the actual problem? How is the final plot supposed to look? – Mark Setchell Oct 03 '14 at 09:48
  • @Miguel No I don't have the the fitting parameters in a separate file. Are you suggesting that I first run the code above estimate the fitting parameters, write them on a file and then later read them from this file to plot? – PyPhys Oct 03 '14 at 10:45
  • @MarkSetchell I can't add a figure to show what I mean, so in words: the final plot has nine curves from data files and for each curve a line fitted to it. Like the pic in section 7 here: [link](http://people.duke.edu/~hpgavin/gnuplot.html) – PyPhys Oct 03 '14 at 11:00
  • Any chance you can upgrade to version 4.6? Then you could use gnuplot's loops and the solution to [gnuplot linear fit within for loop](http://stackoverflow.com/q/24367146/2604213). – Christoph Oct 03 '14 at 11:59
  • @Christoph I don't have the privilege to upgrade on my own, I have made a request though. – PyPhys Oct 03 '14 at 12:53
  • Thanks again @Christoph I got gnuplot 4.6 and using the link you suggested, I'm able to plot data files and fit curves to them. Appreciate your help. – PyPhys Oct 03 '14 at 19:16

2 Answers2

3

Before you write a bash script to generate a gnuplot script, you should think about what your gnuplot script should look like. After that, you can write a bash/whatever script to generate the same gnuplot code.

So, what you want is this:

set xlabel "k"
set ylabel "p(k)"
set term png
set output "MySingleFile.png"


# Note that I've added c and d to the declaration
expon(x, c, d) = c * exp(-x*d)

# This allows to store the fit parameters for each datafile separately
fit expon(x, c1, d1) "dataFile1.data" via c1, d1
fit expon(x, c2, d2) "dataFile2.data" via c2, d2
fit expon(x, c3, d3) "dataFile3.data" via c3, d3

# now plot it. Note: The backslash allows multi line commands
plot \
    "dataFile1.data" notitle pt 1, \
    expon(x, c1, d1) title sprintf('exp(x) = %.2f * e(%.2f)', c1, d1) lt 1,\
    "dataFile2.data" notitle pt 2, \
    expon(x, c2, d2) title  sprintf('exp(x) = %.2f * e(%.2f)', c2, d2) lt 2,\
    "dataFile3.data" notitle pt 3, \
    expon(x, c3, d3) title  sprintf('exp(x) = %.2f * e(%.2f)', c3, d3) lt 3


unset output

Now you can write a bash script based on yours which generates code like mine. However, consider to pipe the gnuplot commands into a separate file and then call gnuplot with this file as parameter. This allows to debug the output of the bash script.

Note that there is no comma at the end of the last line of the command plot. Depending on what you need, your bash script hast to care about, or you just edit your gnuplot file and remove the last comma.

sweber
  • 2,916
  • 2
  • 15
  • 22
1

Sorry, I don't have much time, but I wanted to give you a hand...

If you want to make a loop out of @sweber's code, you can do somethimg like this:

#!/bin/bash    
{ 
cat<<EOF
set xlabel "k"
set ylabel "p(k)"
set term png
set output "MySingleFile.png"
EOF

for i in {1..3}
do
   cat<<EOF
   fit ... something with $i ...
EOF
done

for i in {1..3}
do
   cat<<EOF
   plot ... something with $i ...
EOF
done } | gnuplot

Just remove the | gnuplot at the end to debug or look at the generated code. It is like this:

set xlabel "k"
set ylabel "p(k)"
set term png
set output "MySingleFile.png"
fit ... something with 1 ...
fit ... something with 2 ...
fit ... something with 3 ...
plot ... something with 1 ...
plot ... something with 2 ...
plot ... something with 3 ...
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432