set multiple delimiter with gnuplot - 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

Related

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

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' ...).

Gnuplot error on command "set data s l"

My program has gnuplot script and its first line is
set data s l
But this makes error
"cdia.GNUBAND", line 1: unrecognized option - see 'help set'.
I think it's the version problem and I have to change the "set data s l" command in right way. I searched on web but couldn't find it.. How do I solve this?
That is the shortcut for set data style lines, which is deprecated since version 4.0 (released in 2004). To replace this line, use
set style data lines
This sets the default plotting style for data set to lines, i.e. the commands
set style data lines
plot 'data.dat'
and
plot 'data.dat' with lines
are equivalent.

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".

plot audio data in gnuplot

how could I convert an audio file such as a aiff into a svg using gnuplot? I used sox (sound exchange) to convert an .aiff into a .dat, which I can load now in gnuplot.
I did something similar to:
set terminal svg
set output "test.svg"
plot "test.dat"
I get a svg file, but only with dots / or a lot of x.
How could I connect the dots?
To draw lines between the points, use
plot "test.dat" with lines
Or to keep the point markers as well as the lines, use
plot "test.dat" with linespoints
So your example becomes
set terminal svg
set output "test.svg"
plot "test.dat" with lines
Further tips:
Don't consider every sample:
With large files you may also find it useful to plot only every nth sample with "every n". This will make the plot much faster to generate and will also yield a smaller (but less detailed) svg file.
e.g.
plot "test.dat" every 100 with lines
Ignore .dat file header:
If your sox-produced .dat file has some lines of introductory metadata, such as
; Sample Rate 44100
; Channels 2
you can add the following to have gnuplot consider those lines comments and ignore them.
set datafile commentschars ";"
This will save you having to pre-process your .dat file in order to remove those lines before gnuplot chokes on them.
Plot both left and right channels of stereo audio:
If you're working with a stereo file, you probably want to see both channels.
We can use "multiplot" to lay out the following two plots (of left then right channel) one above the other on a shared x-axis, as many sound-editing programs do.
set multiplot layout 2,1
plot "test.dat" using 1:2 with lines
plot "" using 1:3 with lines
The 1:2 and 1:3 instruct gnuplot which columns of the dat file to use as x and y sources. I'm assuming your stereo .dat file produced by sox looks as mine does, with columns for
- 1: time since beginning of first sample
- 2: normalized sample value of left channel
- 3: normalized sample value of right channel
example snippet:
10.840113 0.20101929 0.17840576
10.840136 0.26062012 0.14831543
10.840159 0.23779297 0.13146973
Putting it together:
Here's a script which puts all of the above together. If you don't have a stereo data file to try this with, you'll want to remove the plot of 1:3 and the multiplot setting.
#!/usr/bin/env gnuplot
set datafile commentschars ";"
set terminal svg
set output "test.svg"
set multiplot layout 2,1
plot "test.dat" using 1:2 every 100 with lines
plot "" using 1:3 every 100 with lines
unset multiplot
Prettification
Finally, I've tweaked the script for presentation (borrowing heavily from the excellent "gnuplot in action" book by Philipp K. Janert):
#!/usr/bin/env gnuplot
set datafile commentschars ";"
set terminal svg
set output "test.svg"
set multiplot layout 2,1
set ylabel "sample value"
set bmargin 0
set format x ""
set ytics -0.8,0.2
set key bottom
plot "test.dat" using 1:2 every 100 with lines lc rgbcolor "#a0a0b0" title "left channel"
set xlabel "time (s)"
set bmargin
set tmargin 0
set format x "%g"
set ytics -1.0,0.2,0.8
set key top
plot "" using 1:3 every 100 with lines lc rgbcolor "#a0a0b0" title "right channel"
unset multiplot
Here's an example output (albeit png):
How to make a .dat file
For anyone following along at home, you can use sox to generate a .dat file from an audio file with the following command:
sox input.wav output.dat
Big file warning: Converting even just 10 seconds of stereo audio at 40kHz will produce a 25Mb output file.
Note that you can also plot the binary data directly:
set terminal svg
set output "test.svg"
plot '< sox test.aiff -t s32 -' binary format='%int32' using 0:1 with lines
Just wanted to document this - well, I was looking for a long time for a Linux command line audio waveform viewer, which could be called from the command line, with a raw binary file as input, and where the format of the data could be specified on the command line.
Audacity can import raw data, but only from the GUI (there is no way to specify raw datafile format through its command line options); while wave viewers like gwave, gtkwave or Gaw - Gtk Analog Wave viewer can either read proper .wav, or SPICE based formats.
And thanks to the answer by #Thor, now I know I can use gnuplot for the purpose. Here is an example command line, which interprets the raw binary data as 16-bit stereo:
gnuplot -p -e "set terminal x11 ; set multiplot layout 2,1 ; plot 0 ls 2, 'data.raw' binary format='%int16%int16' using 0:1 with lines ls 1; plot 0 ls 2, 'data.raw' binary format='%int16%int16' using 0:2 with lines ls 1 ; unset multiplot"
... or broken in several lines:
gnuplot -p -e "set terminal x11 ; set multiplot layout 2,1 ; \
plot 0 ls 2, 'data.raw' binary format='%int16%int16' using 0:1 with lines ls 1; \
plot 0 ls 2, 'data.raw' binary format='%int16%int16' using 0:2 with lines ls 1; \
unset multiplot"
Note that:
you should only use pipe "< ..." if you want to output from a shell command - if you have a file (like above), don't use the pipe (else getting permission denied)
Note the format '%int16%int16' will cause the byte stream to be "grouped" as 2 bytes representing column (channel) 1, the next 2 bytes as column (channel) 2, the next 2 bytes again as column 1, and so on... see gnuplot docs_4.2: Binary General - Format (also related: Gnuplot: How to plot multiple time series from a binary format)
Finally with two independent plots, one using 0:1 and the other using 0:2, we can get a typical waveform rendering (as in accepted answer) - with one channel above the other
Since the --persist option is used above, gnuplot will exit, while the (x11 or wxt) window will remain - and so, the typical gnuplot interaction with the window will not work
Anyways, glad I found this, will save me quite a bit of time, I think :)

gnuplot v4.4: Problem plotting using timeseries x axis

could someone please help me. I'm trying to create a simple chart.
set datafile separator ","
set xdata time
set timefmt "%d/%m/%Y %H:%M:%S"
set format x "%H:%M"
set autoscale y
plot ["13:00":"14:00"] './data.csv' using 1:2 with lines
data.csv:
26/10/2010 13:30:01,1
26/10/2010 13:30:12,2
26/10/2010 13:30:23,3
26/10/2010 13:30:34,4
gives me the error:
line 6: all points y value undefined!
I've tried all manners of timefmt settings!
Many thanks
The problem is defining the xrange, it needs to be the same format timefmt (see ?time_axis)
The following works for me
set datafile separator ","
set xdata time
set timefmt "%d/%m/%Y %H:%M:%S"
set format x "%H:%M"
set autoscale y
set xrange["26/10/2010 13:00:00":"26/10/2010 14:00:00"]
plot './data.csv' using 1:2 with lines
Oh, and I got rid of the blank lines in between each line of data.
If you don't want to edit the file to get rid of the blank data, then you can use awk in gnuplot like so,
plot "<awk '$0!~/^$/ {print $0}' ./data.csv" using 1:2 with lines
for the final command.
EDIT: further info in case there is still a problem (see the comments)
I needed to use the awk command to get the data to plot. This was to remove the blank lines in the data. Combining awk and gnuplot in this fashion works on linux systems, I'm not certain about gnuplot on windows. It could be that certain piping isn't happening, in which case you would have to remove the blank lines before using gnuplot. (you could still use awk for this, but perhaps not in the plot command?)
If you are using linux and the above is not working, then something else is the problem. Perhaps there are old commands stored in the gnuplot session? To make sure we are doing exactly the same thing, I give the shell script that I used (I changed the xrange to fit the data better and make a nicer plot, also notive the \$ instead of $, otherwise the shell misinterprets the $ sign).
Okay: I made the file data.csv.sh in a new folder (in case you have data.csv or data.csv.png files already),:
#!/bin/bash
echo "26/10/2010 13:30:01,1
26/10/2010 13:30:12,2
26/10/2010 13:30:23,3
26/10/2010 13:30:34,4" > "data.csv"
gnuplot<<EOF
set term png small
set output "data.csv.png"
set datafile separator ","
set xdata time
set timefmt "%d/%m/%Y %H:%M:%S"
set format x "%H:%M"
set autoscale y
set xrange["26/10/2010 13:30:00":"26/10/2010 13:31:00"]
plot "<awk '\$0!~/^\$/ {print \$0}' ./data.csv" using 1:2 with lines
set output
set term pop
EOF
Then on the terminal I typed:
chmod +wrx data.csv.sh && ./data.csv.sh
to make the shell script executable and then to run it.
The file data.csv.png looks like the following
All the best
Tom
I just wanted to add to the above discussion in case someone was having the same issues. I was trying to plot a time series, such as:
07/22/13 01:00 120
When I tried to plot using the above procedure I got the bad time format error. I changed my input data to:
07/22/2013 01:00 120
After the change, it ran perfectly. This would make sense because to gnuplot the 07/22/13 is vague. That is, is it 1913, 1813, or 2013 (or any other yy13).

Resources