gnuplot dashed lines in aqua terminal - terminal

I am using gnuplot 4.4 patchlevel 4 on Mac OS X v10.6.8. I'm running a gnuplot script, a simplified version of which is this: (file1, file2,...etc are specified in the terminal before running the script)
reset
set term aqua enhanced font "Times-Roman, 18"
set term aqua dashed
plot file1 u 3:10 w lines lt 1 linecolor rgb "#FF0000",\
file2 u 3:10 w lines lt 1 linecolor rgb "#00FF00",\
file3 u 3:10 w lines lt 1 linecolor rgb "#0000FF",\
file4 u 3:10 w lines lt 1 linecolor rgb "#FF00FF",\
file5 u 3:10 w lines lt 1 linecolor rgb "#00FFFF",\
file6 u 3:10 w lines lt 2 linecolor rgb "#FF0000",\
file7 u 3:10 w lines lt 2 linecolor rgb "#00FF00",\
file8 u 3:10 w lines lt 2 linecolor rgb "#0000FF",\
file9 u 3:10 w lines lt 2 linecolor rgb "#FF00FF",\
file10 u 3:10 w lines lt 2 linecolor rgb "#00FFFF"
files 1-5 are one data set and files 6-10 are another. I would like files 1 through 5 to be plotted with solid lines and files 6 through 10 to be plotted with dashed lines. Is there any way to do this in aqua terminal? According to the built-in help, "lines can be drawn either solid or dashed". I've looked at multiple faqs and docs but the consensus seems to be that it is really difficult or impossible to do? Additionally, does anyone know of any comprehensive documentation on the aqua terminal or on gnuplot commands in general?
Edit: To plot files 6-10 I have been using lw 6 to distinguish them from the 1-5 since I couldn't get dashed lines to work. Would the script above as I have it do this correctly? In other words, is the script doing what I think it is doing? (plotting 1-5 solid lines and 6-8 thicker lines?) I ask because in an attempt to make dashed lines, I replace "lw 6" with "lt 2". This however results in file5 being plotted with dashed lines which is just weird.
Edit 2: I attached my terminal test graphic and there doesn't seem to be any mention of dashed lines?
Edit 3: Updated script to reflect changes made.
Edit 4: Graphic is now of set term aqua enhanced font "Times-Roman, 18" dashed; test

It's not too bad at all actually (at least for me on OS-X 10.5.8 with gnuplot 4.2. I stopped building aquaterm in my newer versions of gnuplot as I don't like that terminal) In the aqua terminal, linetype 1 is solid and linetype 2 is dashed.
set term aqua enhanced font "Times-Roman, 18" dashed
plot sin(x) w lines lt 1 lc rgb "blue", cos(x) w lines lt 2 lc rgb "purple"
To see the linetypes that your version of gnuplot will use for a particular terminal, you can use the test command after setting the terminal (and output if the terminal needs it).
A suggestion for how your code should look:
reset
set term aqua enhanced font "Times-Roman, 18" dashed
plot file1 u 3:10 w lines lt 1 linecolor rgb "#FF0000",\
file2 u 3:10 w lines lt 1 linecolor rgb "#00FF00",\
file3 u 3:10 w lines lt 1 linecolor rgb "#0000FF",\
file4 u 3:10 w lines lt 1 linecolor rgb "#FF00FF",\
file5 u 3:10 w lines lt 1 linecolor rgb "#00FFFF",\
file6 u 3:10 w lines lt 2 linecolor rgb "#FF0000",\
file7 u 3:10 w lines lt 2 linecolor rgb "#00FF00",\
file8 u 3:10 w lines lt 2 linecolor rgb "#0000FF",\
file9 u 3:10 w lines lt 2 linecolor rgb "#FF00FF",\
file10 u 3:10 w lines lt 2 linecolor rgb "#00FFFF"
EDIT
I just looked on a friend's computer. for her (gnuplot 4.4.4, os-X 10.6?) linetype 8 was the first dashed linetype (highlighting the usefulness of the test command).

Related

gnuplot : setting line style in a for loop

I have to plot several curve on a same graph. I necessarly need to use a for loop to do this. I would like to plot the 2 first curves with lines and the others with points. I am able to plot all the curves with lines or all the curves with points but not to change in the same for loop.
Here is the concerned part of my code:
set style line 1 lw 1 lc rgb "green"
set style line 2 lw 1 lc rgb "purple"
set style line 3 pt 1 ps 1.0 lc rgb "red"
set style line 4 pt 2 ps 1.0 lc rgb "red"
set style line 5 pt 3 ps 1.0 lc rgb "red"
plot for [i=1:words(FILES)] myDataFile(i) u (column(1)):((word(UTAUS_ch,i))) ls i title myTitle(i)
I would like to preface "ls i" with "w l" for the 2 first curves and "ls i" for the others. I tried to use a if statement by replacing "ls i" by "if (i < 2) {w l ls i} else {ls i}" but Gnuplot does not expect to find a if statement at this location.
Can someone help me ?
Thank you,
Martin
As mentioned here you probably cannot switch plotting styles within a plot for loop.
So, either you do two separate loops, one with points and the other with lines or you do one loop with linespoints and define all necessary parameters for points and lines as functions (to keep the plot command readable).
As mentioned here, linewidth 0 is not zero but the thinnest possible line which is typically 1 pixel. To make the line disappear completely you have to use linetype -2.
Code:
### lines and points in the same plot for-loop
reset session
LINECOLORS = "red green blue magenta cyan"
LINEWIDTHS = '1.0 4.0 0.0 0.0 0.0'
POINTTYPES = '0 0 5 7 9'
POINTSIZES = '0 0 1.0 2.0 3.0'
TITLES = 'one two three four five'
myLinecolor(i) = word(LINECOLORS,i)
myLinewidth(i) = real(word(LINEWIDTHS,i))
myPointtype(i) = int(word(POINTTYPES,i))
myPointsize(i) = real(word(POINTSIZES,i))
myLinetype(i) = myLinewidth(i) == 0 ? -2 : 1
myTitle(i) = word(TITLES,i)
set samples 31
set key out
plot for [i=1:words(TITLES)] (sin(0.25*x-i)) w lp pt myPointtype(i) ps myPointsize(i) \
lt myLinetype(i) lw myLinewidth(i) lc rgb myLinecolor(i) title myTitle(i)
### end of code
Result:
Addition:
In order to keep the plot command as short and clear as possible you could also define line styles and use it in the plot for command via ls i, with the same result as above.
...
do for [i=1:words(TITLES)] {
set style line i pt myPointtype(i) ps myPointsize(i) \
lt myLinetype(i) lw myLinewidth(i) lc rgb myLinecolor(i)
}
plot for [i=1:words(TITLES)] (sin(0.25*x-i)) w lp ls i title myTitle(i)
Here a way using a macro:
set style line 1 lw 1 lc rgb "green"
set style line 2 lw 1 lc rgb "purple"
set style line 3 pt 1 ps 1.0 lc rgb "red"
set style line 4 pt 2 ps 1.0 lc rgb "red"
set style line 5 pt 3 ps 1.0 lc rgb "red"
set samp 100
set macro
cmd = ''
do for [i=1:10] {s = i<3? 'w l' : 'ls '.i;
cmd = cmd . '"+" us 1:(sin(x-'.i.'/10.)) '.s.' title "key '.i.'",'}
plot [0:2*pi] #cmd

GNUPLOT 5: conditional plotting with timefmt abscissa

I am having hard time applying conditional plotting to data with timefmt abscissa using gnuplot 5.0 patchlevel 6.
I am trying to plot the content of an ASCII file consisting in two columns:
2016-12-01 12
2017-01-01 1
2017-02-01 2
2017-03-01 3
2017-04-01 4
2017-05-01 5
2017-06-01 6
so I just issue:
set timefmt "%Y-%m-%d"
set xdata time
p 'file.dat' u 1:2 w l, '' u 1:($1>strptime("%Y-%m-%d","2017-03-01")?$2:10) w p
I expect the plot to look like a line following the second column and a series of dots, following the line for the last three abscissas or marking the value 10 at the previous ones.
Actually, all the points are at 10. Do you have any clue about what is happening? Many thanks in advance.
Use timecolumn.
p 'file.dat' u 1:2 w l, '' u 1:(timecolumn(1, "%Y-%m-%d")>strptime("%Y-%m-%d", "2017-03-01") ? column(2) : (10)) w p

Matching a Color Gradient to Data in Gnuplot

I have data showing a change over time, and I have used Gnuplot 4.6 to generate the following plot:
Here, I have manually defined eleven line styles to change the color gradually from red (#ff0000) to dark red (#5f0000) as `time' progresses. Here was my input:
# svg
set terminal svg size 600,600 fname 'CMU Sans Serif' fsize '10'
set output 'plot.svg'
# color definitions
set style line 1 lc rgb '#ff0000' lt 1 lw 2 pt 7 # starting light red
set style line 2 lc rgb '#ef0000' lt 1 lw 2 pt 7
set style line 3 lc rgb '#df0000' lt 1 lw 2 pt 7
set style line 4 lc rgb '#cf0000' lt 1 lw 2 pt 7
set style line 5 lc rgb '#bf0000' lt 1 lw 2 pt 7
set style line 6 lc rgb '#af0000' lt 1 lw 2 pt 7
set style line 7 lc rgb '#9f0000' lt 1 lw 2 pt 7
set style line 8 lc rgb '#8f0000' lt 1 lw 2 pt 7
set style line 9 lc rgb '#7f0000' lt 1 lw 2 pt 7
set style line 10 lc rgb '#6f0000' lt 1 lw 2 pt 7
set style line 11 lc rgb '#5f0000' lt 1 lw 2 pt 7
# visual elements
unset key
set xlabel 'x Axis'
set ylabel 'y Axis'
# plot data
plot for [n=2:11] 'data.dat' using 1:n with lines ls (n-1)
Is there a simpler way to get Gnuplot to gradually change the color as it plots multiple lines? I would ideally like to have a single script that can handle an arbitrary number of color gradations depending on the amount of data from the `data.dat' file.
You can e.g. use a function which calculates the colors depending on the iteration counter
# values r, g, b, x must be in the range [0:1]
rgb(r,g,b) = (255*r*256**2 + 255*g*256 + 255*b)
grad(x) = rgb(1 - x*0.7)
set style data lines
plot for [n=2:11] 'data.dat' using 1:2 lc rgb grad((n-2)/9.0)
Alternatively you can define a gradient and select a fractional position for each line
set palette defined (0 '#5f0000', 1 '#ff0000')
set style data lines
plot for [n=2:11] 'data.dat' using 1:2 lc palette frac (n-2)/9.0

GNUPlot - How to control interline spacing in tick labels?

I'm trying to plot a graph that has two-line labels on its xticks. I cannot reduce the font anymore because it becomes unreadable (the plot is part of a 2x2 multiplot).
The problem is that the separation between the two lines in a label is too big, so that they become too close to the labels of the next columns.
I would like to reduce the interline spacing so that the lines of a label become closer between them, but further to the lines of the other labels.
I've thought about placing the labels manually (using a function to compute the position of each line), but before doing it I would like to know if someone has a simpler solution.
Thanks a lot!
I'm using "gnuplot 4.6 patchlevel 4" on Ubuntu 14. The folowing is a MWE:
# Requires gnuplot >= 4.6
set terminal pdf color solid font "Helvetica, 10" enhanced size 4, 3.72
set output 'mwe.pdf'
set border 3 lc rgb "#000000"
set bmargin 9
set ylabel offset -1
TicksFont = ", 10"
Title2Font = ", 14"
set yrange[0:180 < * ]
set format y "%.0f%%"
set xtics out scale 0, 0 nomirror rotate by 90 right offset 0,0 font TicksFont
set ytics out nomirror font TicksFont
unset key
set datafile separator ";"
set style fill transparent solid 1.0 border -1
set style data boxes
set boxwidth 1.0
#Bottom-left plot
set title "C) Third (sub)plot" font Title2Font
plot '-' using ($0):2:(0xFF8080):xtic(1) notitle lc rgb variable
# Label; Value
01. Aaaaa:\nAaaaaaaaa(AA); 100
02. Bbbbb:\nBbbbbbbbbbbb(BB); 20
03. Ccccc: Ccccccc(Ccc),\nCccccccc(CCC); 30
04. Dddd: DDDD,\nDDDDDDDDDDDD(DD); 40
;NaN
01. Aaaaa:\nAaaaaaaaa(AA); 100
02. Bbbbb:\nBbbbbbbbbbbb(BB); 20
03. A single-liner; 30
04. Dddd: DDDD,\nDDDDDDDDDDDD(DD); 40
;NaN
01. Aaaaa:\nAaaaaaaaa(AA); 100
02. Bbbbb:\nBbbbbbbbbbbb(BB); 20
03. A single-liner; 30
04. Dddd: DDDD,\nDDDDDDDDDDDD(DD); 40
05. Eeee: EEEE,\nEEEEEEEEEEEE(EE); 50
end;
From gnuplot you cannot directly control the line height used for the labels. But there is a quite dirty workaround for your problem:
You can split your label at the new line character, change the font size of each line with the enhanced label syntax, but set a different font size for the new line character. So a label
set label at 0,0 "first line\nsecond line" font ",10"
is changed to
set label at 0,0 "{/=10 first line}\n{/=10 second line} font ",8"
And your script changes to:
# Requires gnuplot >= 4.6
set terminal pdf color solid font "Helvetica, 10" enhanced size 4, 3.72
set output 'mwe.pdf'
set border 3 lc rgb "#000000"
set bmargin 9
set ylabel offset -1
TickSize = 10
TicksFont = ", ".TickSize
Title2Font = ", 14"
set yrange[0:180 < * ]
set format y "%.0f%%"
set xtics out scale 0, 0 nomirror rotate by 90 right offset -0.1,0 font ",8"
set ytics out nomirror font TicksFont
unset key
set datafile separator ";"
set style fill transparent solid 1.0 border -1
set style data boxes
set boxwidth 1.0
#Bottom-left plot
set title "C) Third (sub)plot" font Title2Font
set_label_size(s) = sprintf('{/=%d %s}', TickSize, s)
label(s) = strstrt(s, "\n") ? set_label_size(s[:strstrt(s, "\n")-1])."\n".set_label_size(s[strstrt(s, "\n")+1:]) : set_label_size(s)
plot '-' using ($0):2:(0xFF8080):xtic(label(strcol(1))) notitle lc rgb variable
# Label; Value
01. Aaaaa:\nAaaaaaaaa(AA); 100
02. Bbbbb:\nBbbbbbbbbbbb(BB); 20
03. Ccccc: Ccccccc(Ccc),\nCccccccc(CCC); 30
04. Dddd: DDDD,\nDDDDDDDDDDDD(DD); 40
;NaN
01. Aaaaa:\nAaaaaaaaa(AA); 100
02. Bbbbb:\nBbbbbbbbbbbb(BB); 20
03. A single-liner; 30
04. Dddd: DDDD,\nDDDDDDDDDDDD(DD); 40
;NaN
01. Aaaaa:\nAaaaaaaaa(AA); 100
02. Bbbbb:\nBbbbbbbbbbbb(BB); 20
03. A single-liner; 30
04. Dddd: DDDD,\nDDDDDDDDDDDD(DD); 40
05. Eeee: EEEE,\nEEEEEEEEEEEE(EE); 50
end;
Before (left) and after (right):
You can switch to the epslatex terminal and use latex syntax on your gnuplot script directly. Then you can use the \vspace{} command with a negative argument to decrease the interline spacing, something like this:
\shortstack{01. Aaaaa: \vspace{-0.2em} \\ Aaaaaaaaa(AA)}
Although you'll need to escape backslashes:
\\shortstack{01. Aaaaa: \\vspace{-0.2em} \\\\ Aaaaaaaaa(AA)}
Would it be acceptable to just change the size of the whole plot, for example by changing the plot width from 4 inches to 6 and the height from 3.72 to 5.58?
This way the aspect ratio is preserved if you include it in a different document.
Before:
After:

Gnuplot: plotting the maximum of two files

let's assume I have two files formatted like this:
x --- y
0 --- 2
1 --- 2.4
2 --- 3.6
which differ for the values of y.
is there a way to plot a single graph that is, for every x, the maximum value of y between the two files?
Dunno if explained my self sufficiently well.
I was trying with conditional sentences but I couldn't find any expression that let me search in 2 different files
There is no way to combine two files or more in a single plot with gnuplot only. You must use an external tool to do this, e.g. the command line utility paste:
max(x, y) = (x > y ? x : y)
plot '< paste fileA.txt fileB.txt' using 1:(max($2, $4))
The y values are contained in the second and fourth columns.
This next version uses a python script with numpy to concatenate the files, but any other scripting language would also do:
"""paste.py: merge lines of two files."""
import numpy as np
import sys
if (len(sys.argv) < 3):
raise RuntimeError('Need two files')
A = np.loadtxt(sys.argv[1])
B = np.loadtxt(sys.argv[2])
np.savetxt(sys.stdout, np.c_[A, B], delimiter='\t')
To plot, use:
max(x, y) = (x > y ? x : y)
plot '< python paste.py fileA.txt fileB.txt' using 1:(max($2, $4))
Just for the records, there is a way with gnuplot only to get the maximum out of two files.
For sure, it's probably more efficient to use Linux tools or on Windows install, e.g. CoreUtils from GnuWin, but with gnuplot-only you are surely platform independent without extra installations.
Assumption: both files have same number of lines and identical x-values
Edit: simplified code which works for all gnuplot versions>=4.6.0 and faster version for gnuplot>=5.2.0 using an array.
The simple "trick" is to write the y value of one file into a single string and address them via word(). For small data this is ok, but for larger data (>10'000 lines) it might get slow because apparently it runs with something like O(N^2). Just to get an idea (on my system): 1'000 lines take 0.4 seconds, 10'000 lines take 13 seconds and 20'000 lines already take 45 seconds.
As comparison, the array-solution for gnuplot>=5.2.0 just takes about 3 seconds for 10'000 lines.
Data:
SO19079146_1.dat
1 1.1
2 2.1
4 1.5
6 1.3
7 0.2
8 1.5
9 2.1
SO19079146_2.dat
1 2.1
2 2.5
4 1.5
6 0.3
7 0.7
8 1.0
9 1.4
Script 1: (works for gnuplot>=4.6.0, March 2012)
### plot maximum from two files
reset
FILE1 = 'SO19079146_1.dat'
FILE2 = 'SO19079146_2.dat'
data2 = ''
stats FILE2 u (data2=data2.' '.sprintf("%g",$2)) nooutput
set offset 1,1,1,1
max(col) = (i=int(column(0)+1), y1=column(col), y2=real(word(data2,i)), y1>y2 ? y1 : y2)
plot FILE1 u 1:(max(2)) w lp pt 7 lw 8 lc rgb "grey" ti "Max", \
'' u 1:2 w lp pt 7 lc rgb "red" ti "Data1", \
FILE2 u 1:2 w lp pt 7 lc rgb "blue" ti "Data2"
### end of script
Script 2: (works for gnuplot>=5.2.0, Sept. 2017)
### find the maximum out of two files/datablocks (gnuplot>=5.2.0)
reset session
FILE1 = 'SO/SO19079146_1.dat'
FILE2 = 'SO/SO19079146_2.dat'
stats FILE1 u 0 nooutput
array A[STATS_records]
stats FILE2 u (i=int($0+1), A[i]=$2) nooutput
set offset 1,1,1,1
max(col) = (i=int(column(0)+1), y1=column(col), y2=A[i], y1>y2 ? y1 : y2)
plot FILE1 u 1:(max(2)) w lp pt 7 lw 8 lc "grey" ti "Max", \
'' u 1:2 w lp pt 7 lc "red" ti "Data1", \
FILE2 u 1:2 w lp pt 7 lc "blue" ti "Data2"
### end of script
Result: (identical for all above versions)

Resources