Gnuplotting

Create scientific plots using gnuplot

April 2nd, 2012 | No Comments

Since last month the new Gnuplot version 4.6 is officially available. There are a lot of interesting changes in this new version and we will cover the bigger ones within the next posts. Here we start with, in my opinion, the nicest new feature: block-structured conditions and loops.

Until 4.6 an iteration over different lines of code was only possible with the help of an extra file. This technique was used, for example, for the gif animation entry. There the loop was executed by

t = 0
end_time = 1
load 'bessel.plt'

with the file bessel.plt containing the code to execute within the loop

# bessel.plt
t = t + 0.02
outfile = sprintf('animation/bessel%03.0f.png',50*t)
set output outfile
splot u*sin(v),u*cos(v),bessel(u,t) w pm3d ls 1
if(t<end_time) reread;

This can now be reformulated in a much shorter way by applying the new do command and the block-structure given by the { }

do for [t=0:50] {
    outfile = sprintf('animation/bessel%03.0f.png',t)
    set output outfile
    splot u*sin(v),u*cos(v),bessel(u,t/50.0) w pm3d ls 1
}

Now there is no need for an additional file. The only thing to consider is the change of the index t, because for the for-loop t has to be an integer.

The block-structure can in the same way be applied to the if-statement.

February 20th, 2012 | No Comments

Most of you will probably know the problem of visualizing more than two dimensions of data. In the past we have seen some solutions to this problem by using color maps, or pseudo 3D plots. Here is another solution which will just plot a bunch of lines, but varying their individual colors.

colored lines

Fig. 1 Plot of interaural time differences for different frequency channels, indicated by different colors (code to produce this figure, data)

For this we first define the colors we want to use. Here we create a transition from blue to green by varying the hue in equal steps. The values can be easily calculated with GIMP or any other tool that comes with a color chooser.

set style line 2  lc rgb '#0025ad' lt 1 lw 1.5 # --- blue
set style line 3  lc rgb '#0042ad' lt 1 lw 1.5 #      .
set style line 4  lc rgb '#0060ad' lt 1 lw 1.5 #      .
set style line 5  lc rgb '#007cad' lt 1 lw 1.5 #      .
set style line 6  lc rgb '#0099ad' lt 1 lw 1.5 #      .
set style line 7  lc rgb '#00ada4' lt 1 lw 1.5 #      .
set style line 8  lc rgb '#00ad88' lt 1 lw 1.5 #      .
set style line 9  lc rgb '#00ad6b' lt 1 lw 1.5 #      .
set style line 10 lc rgb '#00ad4e' lt 1 lw 1.5 #      .
set style line 11 lc rgb '#00ad31' lt 1 lw 1.5 #      .
set style line 12 lc rgb '#00ad14' lt 1 lw 1.5 #      .
set style line 13 lc rgb '#09ad00' lt 1 lw 1.5 # --- green

Then we plot our data with these colors and get Figure 1 as a result.

plot for [n=2:13] 'itd.txt' u 1:(column(n)*1000) w lines ls n

There the interaural time difference (ITD) between the right and left ear for different frequency channels ranging from 236 Hz to 1296 Hz is shown. As can be seen the ITD varies depending on the incident angle (azimuth angle) of the given sound.

Another possibility to indicate the frequency channels given by the different colors is to add a colorbox to the graph as shown in Figure 2.

Colored lines

Fig. 2 Plot of interaural time differences for different frequency channels, indicated by different colors as shown in the colorbox (code to produce this figure, data)

To achieve this we have to set the origin and size of the colorbox ourselves. Note, that the notation is not the same as for a rectangle object and uses only the screen coordinates which is a little bit nasty. In addition we have to define our own color palette, as has been discussed already in another colorbox entry. In a last step we add a second phantom plot to our plot command by plotting 1/0 using the image style in order to get the colorbox drawn onto the graph.

set colorbox user horizontal origin 0.32,0.385 size 0.18,0.035 front
set cbrange [236:1296]
set cbtics ('236 Hz' 236,'1296 Hz' 1296) offset 0,0.5 scale 0
set palette defined (\
    1  '#0025ad', \
    2  '#0042ad', \
    3  '#0060ad', \
    4  '#007cad', \
    5  '#0099ad', \
    6  '#00ada4', \
    7  '#00ad88', \
    8  '#00ad6b', \
    9  '#00ad4e', \
    10 '#00ad31', \
    11 '#00ad14', \
    12 '#09ad00' \
    )
plot for [n=2:13] 'itd.txt' u 1:(column(n)*1000) w lines ls n, \
   1/0 w image

November 29th, 2011 | 2 Comments

A spectrogram is a time-frequency representation that shows how the spectral content of a signal varies with time. In Fig. 1 the spectrogram of the German sentence “Achte auf die Autos” is shown.

Spectrogram

Fig. 1 Spectrogram plotted with plot (code to produce this figure, data)

The spectrogram is plotted as mentioned in the color maps entry.

plot 'spec.dat' binary matrix with image

In addition the letters were putted on the graph at their corresponding time of occurrence. The letters itself and their positions are stored in the two lists syl and xpos. In order to access the single entries of these lists within a for loop the function word is needed.

# Adding the syllables
syl  = 'A    ch   te   a    u    f    d    ie   A    u    t    \
o    s   '
xpos = '0.15 0.22 0.36 0.44 0.49 0.56 0.62 0.66 0.89 1.01 1.16 \
1.26 1.42'
set for [n=1:words(syl)] label word(syl,n) at word(xpos,n),6800

Another way to plot the spectrogram is by using splot which will result in a different kind of smoothing algorithm of the spectrogram, as can be seen in Fig. 2.

Spectrogram

Fig. 2 Spectrogram plotted with splot (code to produce this figure, data)

But to get this result we have to fix some of the margins, because plot is two-dimensinal and splot is three-dimensional which is not desired here.

set border 10 front ls 11
set tmargin at screen 0.75
set bmargin at screen 0.25
set rmargin at screen 0.95
set lmargin at screen 0.15

October 10th, 2011 | No Comments

In the last entry we have seen how to use a color map to represent matrix data. Another way to visualize such kind of data is to code their values not as color, but as height information using so called pseudo 3D plots.

Pseudo 3D plot

Fig. 1 Pseudo 3D plot of basilar membrane activity (code to produce this figure, data)

Suppose we have some data like spectra with different parameters, slightly shifted and plotted into the same figure, or different oscillations over time as shown in Fig. 1. There, the movement of the basilar membrane to an input stimuli dependent on the center frequency in ERB is plotted over time. The movement on the basilar membrane is dependent on the frequency of the incoming stimulus, with different frequencies acting on different places along the membrane. In order to plot this kind of data the for command of Gnuplot can be used to iterate through the data. The pseudo 3D effect is realized by shifting the data in every iteration one ERB by the +ii part and the usage of filledcurves to overwrite not visible parts of the plot with white color.

set style fill solid 1.0 border rgb 'black'
plot for [ii=25:1:-1] 'bmm.txt' u (f(column(ii))+ii) \
    w filledcu y1=-2 ls 1

The amplitude of the data was originally stored in order to fit in a plot given in Hz. Hence, we have to convert the data into ERB. This is done by the function f. As arguments to the function the values of each column are given in the iteration. Therefore, the column number is indexed by the column function.

May 6th, 2011 | No Comments


loudspeaker circle

Fig. 1 A circular loudspeaker array drawn with the object command (code to produce this figure, set_loudspeaker function)

In one of the last entries we have seen how to plot a loudspeaker with Gnuplot.
This time we will have a look at the case of setting more than one loudspeaker to your plot. Furthermore we allow the placement of the loudspeakers after entries in a data file.
Let us assume we have a data file containing the x position, y position and orientation phi of a single loudspeakers per line. Now we have to read the data with Gnuplot and set the objects according to the data. This can be done by a dummy plot, because by applying the plot command, variables can be stored. For the dummy plot we setting the output of the plot command to table and use /dev/null as the place to write the data.

# --- Read loudspeaker placement from data file
set table '/dev/null'
add_loudspeaker(x,y,phi) = sprintf(\
    'call "set_loudspeaker.gnu" "%f" "%f" "%f" "%f";',x,y,phi,0.2)
CMD = ''
plot 'loudspeaker_pos.dat' u 1:(CMD = CMD.add_loudspeaker($1,$2,$3))
eval(CMD)
unset table

The plot command now enables us to add the data from the file to the variable CMD, which is then executed by the eval command. To create the variable, the add_loudspeaker function creates a string with the data for every single line of the data file. The eval(CMD) calls the set_loudspeaker.gnu function once for every single data line, which corresponds to a single loudspeaker. The set_loudspeaker.gnu function itself does the same as we have done in the draw a single loudspeaker entry, but in addition it uses a rotation matrix to change the orientation of the single loudspeakers.

After having set the loudspeakers, we add some activity to three of the loudspeakers and finally get the result in Fig. 1.

# --- Plot loudspeaker activity
set parametric
fx(t,r,phi) = -1.5*cos(phi)+r*cos(t)
fy(t,r,phi) = -1.5*sin(phi)+r*sin(t)
set multiplot
set trange [-pi/6+pi/8:pi/6+pi/8]
plot for [n=1:3] fx(t,n*0.25,pi/8),fy(t,n*0.25,pi/8) w l ls 2
unset object
set trange [-pi/6-pi/8:pi/6-pi/8]
plot for [n=1:3] fx(t,n*0.25,-pi/8),fy(t,n*0.25,-pi/8) w l ls 2
set trange [-pi/6:pi/6]
plot for [n=1:3] fx(t,n*0.25,0),fy(t,n*0.25,0) w l ls 1
unset multiplot

The three waves before the desired loudspeakers are plotted within an iteration that effects the radius by using the for command. The unset object is executed after the first plot in the multiplot environment, because the loudspeakers should only be drawn once.