Is using a gnuplot variable in an external datafile manipulation command possible? - linux

Using an external datafile manipulation cmd in gnuplot looks like
plot '<(grep "1" "/path/datafile")' using 1:2 ...
Can we use a gnuplot variable in such a cmd like in
plot for [i=1:5] '<(grep "i" "/path/datafile")' using 1:2 ...
where "i" should be the gnuplot variable i.
Is it possible to hand over the gnuplot variable to the external command and how?
Thx!

You can build a string command using the concatenation operator ".". Eg
plot for [i=1:5] "<(grep '".i."' /path/datafile)" using 1:2 ...
You might want to grep for something less ambiguous than single digits like 1 that are likely to match within any number. For example, add word delimiters like \b, or even just a leading space. This is why I added the single quoting of the value as a preliminary step (we are generating grep '1' ...).

Related

GNUPlot: Auto-plot all columns from standard in without extra logic/semantic noise

Suppose I have the following file:
0 a b c
1 1 2 2
2 4 4 2
3 8 6 2
And I want to send it from the command line:
cat foofile | gnuplot -e 'file="/dev/stdin"' plot.p
With the following plotfile:
set key outside
plot for [col=2:4] file using 0:col with lines title columnheader
Now, suppose I would like to send GNUPlot an arbitrary columnar file with anywhere from 1:N columns, where N is arbitrary.
Since I am opening a pipe from within GNUPlot, it seems that I will not be able to read from it to determine the number of columns. How do I tell GNUPlot (in a clean way) to simply plot each column until there are none left to plot?
plot for [col=2:*] file using 0:col with lines title columnheader
However, if you know what the file name is in order to issue the "cat" command you would do better to just pass the filename to gnuplot rather than using a pipe.
gnuplot -e 'file="foofile"' plot.p
Alternatively, you can feed the input via channels other than /dev/stdin. Here is an excerpt from the documentation section for piped-data:
On systems with an fdopen() function, data can be read from an arbitrary file
descriptor attached to either a file or pipe. To read from file descriptor
`n` use `'<&n'`. This allows you to easily pipe in several data files in a
single call from a POSIX shell:
$ gnuplot -p -e "plot '<&3', '<&4'" 3<data-3 4<data-4
$ ./gnuplot 5< <(myprogram -with -options)
gnuplot> plot '<&5'

set multiple delimiter with gnuplot

I'm doing some simulations in OpenFOAM, using probes to get a time series of the velocity in a point. The output file has the following delimiter setup.
if it is possible, what would be the command to set the delimiter ?? when using gnuplot
set datafile separator '???'
Bonus info if I remove all ( and ) and use the default command the plot "plots"
plot "U" using 1:2
You can use
plot "U" using 1:2 "%lf (%lf %lf %lf)"
This format specifies your data format in the plot command. See help using for more details on this and the using examples for more complex examples.
If you don't want to type this each time, and you have a copy of gnuplot compiled with support for string macros, you also can do
dformat = "\"%lf (%lf %lf %lf)\""
plot "U" using 1:2 #dformat
which will expand the format specifier into the command. See help macros for more on this.
I would suggest to use sed :
plot "< sed 's|[()]||g' U" u 1:2

Iterating over powers of two in gnuplot

I want to plot the data stored in bunch of files using gnuplot. If the files were named using sequential numbers, (eg. "1.dat" "2.dat", ...) I'd use something like
plot for [i=1:10] i.'.dat' u 1:2 w lp t 'I='.i;
However, the files are now named using powers of 2, i.e. "2.dat", "4.dat", "8.dat", .... I tried
plot for [i=1:10] (2**i).'.dat' u 1:2 w lp t 'I='.(2**i);
but I get the error
STRING operator applied to non-STRING type
I suppose this happens because gnuplot considers (2**i) as a floating point number rather than integer.
I'm sure there is a way to do what I want to do but as I'm very new to using the control statements of gnuplot I cannot find out how. Could someone please help me?
You can use sprintf to convert a number to a string:
plot for [i=1:10] sprintf('%d',2**i).'.dat' u 1:2 w lp t 'I='.(2**i)
Interestingly, concatenating (2**i) with 'I=' in the title causes no problems.
Try using an empty string ("") to commence the string concatenation operation. That is "".(2**i).".dat" instead of (2**i).".dat".

gnuplot generate plot command with sprintf?

I want to generate a gnuplot plot command programmatically, like:
plotline = sprintf("'datafile1.dat' using %d:3 with points, '%s' using %d:3 with points",i,targfile,i)
plot plotline
Where 'plotline' in the second line is expanded to produce and execute a full command like:
plot 'datafile1.dat' using 8:3 with points, 'datafile2.dat' using 8:3 with points
I want to do this in order to echo 'plotline' in the terminal and so be certain exactly what is being shown while cycling through a set of columns / datafiles / whatever inside a loop in a gnuplot script.
Is there / what is the syntax to do this, or can you suggest another approach to report the plot command as executed (without splitting into a plot command and a separate set of commands to report the current variable states).
Thanks!
In order to construct such a plot command from some strings, you can use eval to execute the commands contained in a string:
plotline = 'x title "mytitle"'
eval('plot '.plotline)
Alternatively you can use set macros:
set macros
plotline = 'x title "mytitle"'
plot #plotline
This replaces #plotline with the content of the string variable plotline before executing the command. Using plot plotline interpretes the content of plotline as file name. Note, that as of version 4.6 macros don't work properly in loops, but eval works fine.
BTW: If you don't specify your own title, then the actual plot statement is written in the plot legend. But that can't be written to the terminal output.

Display underscore rather than subscript in gnuplot titles

Short question:
How do I display the _ (underscore) character in a title in gnuplot that is assigned from a variable name in gnuplot?
Details:
I have something like the following code:
items = "foo_abc foo_bcd bar_def"
do for [item in items] {
set title item
set output item.eps
plot item."-input.txt" using 1:2 title item with linespoints
}
This works fine with gnuplot except that the title get changed from foo_abc to fooabc. I don't know if I want to use an escape character because I don't want that to be in the file name. I've tried a couple of different options with single vs. double quotes but I haven't found what I need yet.
Instead of foo_abc, write foo\\\_abc.
Most gnuplot commands which generate labels accept a noenhanced keyword which will prevent gnuplot from using enhanced text for just that string. In this case, it should be sufficient to just do:
set title item noenhanced
An alternative is to create a function which will remove the unwanted text from the string when passing it to set output:
remove(x,s)=(i0=strstrt(s,x),i0 ? remove(x,s[:i0-1].s[i0+strlen(x):]):s)
# Makes me wish gnuplot syntax was more pythonic :-p
#TODO: Write a `replace` function :-). These just might go into my ".gnuplot" file...
I use an inline function to find the index of the first occurrence of x in the string s. I then remove that occurrence via string concatenation and slicing and recursively call the function again to remove the next occurence. If the index isn't found (strstrt returns 0) then we just return the string that was put in. Now you can do:
set output remove('\',item)
set title item
The underscore comes from treating titles as "enhanced text". Turn that off using
set key noenhanced
If you are using the enhanced eps terminal, that is the reason you need to escape the underscore in the first place. There was another related question today which explains the issue a bit. When you set the terminal, try:
set terminal postscript noenhanced <whatever else here...>
That works for me (Arch linux, gnuplot 4.7.0). If the enhanced terminal is essential, below is a partial solution I found. The assumption is that the underscore always appears in the same place in the string.
set terminal postscript enhanced
items = 'foo\_abc foo\_bcd bar\_def'
do for [item in items] {
set output item[1:3].item[5:*].'.eps'
set title item
plot sin(x)
}
This way you can escape the underscore and not have the \ appear in the filename. Note the use of single quotes for the 'items' string; see the previously linked question for details.
I had the same problem about the underscore in the title: such as I needed to write 4_3 subframe and I needed the enhanced postscript. The SIMPLEST way turned out to be from the adjacent post: ``If you are using the enhanced eps terminal, that is the reason you need to escape the underscore in the first place. There was another related question today which explains the issue a bit." - How is # produced in gnuplot?
So, I followed their advice and this worked:
plot 'LC.stats' u 3:4 ti "{/=15 1350 stars in C18 4\_3 subframe}" -
Double escape character before the underscore.

Resources