gnuplot set two keys side by side and share a title? - gnuplot

This is my figure:
I want to change the keys to this:
Below is my code, what should I do?
set tmargin at screen 0.995; # top and right usually close to 1
set rmargin at screen 0.995;
set bmargin at screen 0.05;
set lmargin at screen 0.05;
set xr[0:0.24]
set yr[0:0.24]
set xtics border offset 0,0.4 0,0.05,0.2
set ytics border offset 0.8,0 0,0.05,0.2
set xlabel 'RHS' offset 0,3
set ylabel 'LHS' offset 9,0
set key at 0.22,0.1
plot '-' w p ps 2 pt 11 lc 8 title "$\kappa$",\
'-' w p ps 2 pt 7 lc 8,\
'-' w p ps 2 pt 9 lc 8,\
'-' w p ps 2 pt 13 lc 8,\
'-' w p ps 2 pt 10 lc 8,\
'-' w p ps 2 pt 6 lc 8,\
'-' w p ps 2 pt 8 lc 8,\
'-' w p ps 2 pt 12 lc 8,\
x dashtype 2 lc 8
0.208555 0.204212
e
0.108604 0.107899
e
0.055720 0.055651
e
0.037514 0.037498
e
0.208555 0.230125
e
0.108604 0.115062
e
0.055720 0.057531
e
0.037514 0.038354
e
I didn't find a legend on how to do this juxtaposition in the website, hope someone can teach me.

There is the key option maxrows (check help key). With this you can limit the number of rows in the legend, however, depending on whether you need a title for x you may need to play other tricks.
However, the horizontal space between the columns is rather large.
You could reduce the space for the symbol (actually line) in the legend via samplen 0
and use the option reverse, this would place the titles between the symbols, unfortunately not centered.
However, this still doesn't look too good, and even worse if your titles do not have the same length.
If you want to get the symbols closer, you could also use multiplot (check help multiplot) to overlay shifted legends, but I would call this rather cumbersome.
I minimized your script a little.
Script:
### shared title in legend
reset session
$Data <<EOD
0.208555 0.204212
0.108604 0.107899
0.055720 0.055651
0.037514 0.037498
0.208555 0.230125
0.108604 0.115062
0.055720 0.057531
0.037514 0.038354
EOD
set xr[0:0.24]
set yr[0:0.24]
set xlabel 'RHS'
set ylabel 'LHS'
set key at graph 0.9, 0.4
set key maxrows 4 title "Legend title" offset -3,0.2 font ",13"
set key samplen 0 reverse
myPts = "11 7 9 13 10 6 8 12"
myPt(i) = int(word(myPts,i))
myTitles = "title1 title2 title3 title4"
myTitle(i) = i>words(myTitles) ? ' ' : word(myTitles,i)." "
plot for [i=1:8] $Data u 1:2 every :::i-1::i-1 w p ps 2 pt myPt(i) lc 8 ti myTitle(i), \
x w l dt 2 lc 8 notitle
### end of script
Result:
Addition:
Here would be the multiplot solution. Since you are using fixed margins in your original script anyway, it is not too much extra effort. You need to play with the graph coordinates of the second key to get the desired placement.
Script:
### shared title in legend using multiplot
reset session
$Data <<EOD
0.208555 0.204212
0.108604 0.107899
0.055720 0.055651
0.037514 0.037498
0.208555 0.230125
0.108604 0.115062
0.055720 0.057531
0.037514 0.038354
EOD
set xr[0:0.24]
set yr[0:0.24]
set xlabel 'RHS'
set ylabel 'LHS'
set margin 10,5,4,2
set key at graph 0.9, 0.4
set key title "Legend title" offset -3,0.2 font ",13"
set key samplen 0 reverse
myPts = "11 7 9 13 10 6 8 12"
myPt(i) = int(word(myPts,i))
myTitles = "title1 title2 title3 title4"
myTitle(i) = i>words(myTitles) ? ' ' : ' '.word(myTitles,i)
set multiplot
plot for [i=1:4] $Data u 1:2 every :::i-1::i-1 w p ps 2 pt myPt(i) lc 8 ti myTitle(i), \
x w l dt 2 lc 8 notitle
set key at graph 0.8,0.4 title " "
unset border
unset tics
unset xlabel
unset ylabel
plot for [i=5:8] $Data u 1:2 ever :::i-1::i-1 w p ps 2 pt myPt(i) lc 8 ti " "
unset multiplot
### end of script
Result:

Related

How to make "filledcurves" change color when two or more meet? (GNUPlot)

I have created a graph that uses lines for the average of my data and filledcurves for the error (average-error, average+error). My problem is that the last filledcurves that is plotted, covers all other fills, even though I have set its transparency. I want to change this so that when two or more filledcurves meet the color is changed and thus the errors are clearly shown for all lines.
My script is:
set datafile separator whitespace
set style line 1 lc rgb '#aa5500' lt 1 lw 2 pt 7 ps 1
set style line 2 lc rgb '#55aaff' lt 1 lw 2 pt 7 ps 1
set style line 3 lc rgb '#aa557f' lt 1 lw 2 pt 7 ps 1
set style line 4 lc rgb '#55007f' lt 1 lw 2 pt 7 ps 1
set style line 5 lc rgb '#005500' lt 1 lw 2 pt 7 ps 1
set style line 6 lc rgb '#0055ff' lt 1 lw 2 pt 7 ps 1
set tics nomirror
set tics front
set style line 12 lc rgb '#808080' lt 0 lw 1
set grid front ls 12
set output 'network_utilization_servers_3_2.png'
set terminal png size 1000,800
set style fill transparent solid 0.25
set style fill noborder
set xrange[0:77]
set yrange[0:1500]
set xlabel "Time (seconds)" font ",12"
set ylabel "Incoming Traffic (KB/s)" font ",12"
set title "Network Utilization in the Servers" font "Helvetica,16"
set key box title "Server" width 10
plot for [i=0:|Group|-1] $Data3 u ($2-6):($3-$4):($3+$4) index i with filledcurves ls i+1 notitle, \
for [i=0:|Group|-1] $Data3 u ($2-6):3:4 index i w lines ti sprintf("%g",Group[i+1]) ls i+1
and my pragh:
My goal is something like this:
Is there a way to achieve this?

Simple heaviside function graphic with gnuplot?

I basically want this (first diagram) done with gnuplot. I've searched and found nothing exactly like this. I can do a good heaviside without the little circles at the end and start of the two lines, but I can't seem to get it with the little circles. Actually, the second diagram would be nice to know too. The third too, but I'm not greedy.
Just for the records and completeness... although you can define a function
H(x) = x<0 ? 0 : 1
If you plot
plot H(x) w l
the line will be continuous at zero and of course without points.
So, another suggestion with just two columns x,y and variable pointtype would be the following.
Code:
### Heaviside function
reset session
$Heaviside <<EOD
-2 0
0 0
0 0.5
0 1
2 1
EOD
set yrange [-1:2]
set ytics 1
unset key
set multiplot layout 3,1
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:($0==1||$0==3?$2:NaN):($0==3?7:6) w p pt var lc 0
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:($0==1||$0==2||$0==3?$2:NaN):($0==2?7:6) w p pt var lc 0
set xrange [0:4]
a = 3
plot $Heaviside u ($1+a):2 w l lc 0, \
'' u ($1+a):($0==1||$0==3?$2:NaN):($0==3?7:6) w p pt var lc 0
unset multiplot
### end of code
Result:
Addition:
A variation with shorter and less confusing plot command, but using 4 columns together with variable pointtype. This will give the same result as above.
Code:
### Heaviside function
reset session
$Heaviside <<EOD
-2 0 NaN NaN
0 0 6 6
0 0.5 NaN 7
0 1 7 6
2 1 NaN NaN
EOD
set yrange [-1:2]
set ytics 1
unset key
set multiplot layout 3,1
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:2:3 w p pt var lc 0
plot $Heaviside u 1:2 w l lc 0, \
'' u 1:2:4 w p pt var lc 0
set xrange [0:4]
a = 3
plot $Heaviside u ($1+a):2 w l lc 0, \
'' u ($1+a):2:3 w p pt var lc 0
unset multiplot
### end of code
Addition 2:
In order to finalize the answer, here is an approach to plot functions containing the Heaviside function.
Instead of plotting from a datablock with fixed x-values (as in the two examples above) it uses the current x-range. Note, for example the syntax plot '+' u 1:(sin($1)) is basically identical with plot sin(x).
Apparently, setting the line color via lc rgb -1 does not plot a line, which can be used here to interrupt the line. You may want to increase the samples, e.g. set samples 300 to avoid a gap between the points and the function.
Code:
### plotting Heaviside function and functions containing Heaviside function
# including line interruption and inclusion/exclusion points
reset session
Heaviside(x,a) = x<a ? 0 : 1 # definition of Heaviside function
array Hpoints[2] = [6,7] # array for plotting "Heaviside points"
Hcolor(x) = (x0=x1, x1=x, x0<a && x1>=a ? -1 : 0xff0000) # set color -1 for line interruption
dx(n) = 1e-3*(2*n-1) # small dx to get y-value of points close to break
f(x,a) = 50/(x**2+2)*cos(4*x) * Heaviside(x,a)
unset key
set multiplot layout 2,1
a = 2.0
set yrange[-1:2]
plot x1=NaN '+' u 1:(Heaviside(x,a)):(Hcolor(x)) w l lc rgb var, \
Hpoints u (a):(Heaviside($1,a)):(Hpoints[$0+1]) w p pt var lc rgb Hcolor(NaN)
a= 0
set samples 300
set yrange[-25:35]
plot x1=NaN '+' u 1:(f(x,a)):(Hcolor(x)) w l lc rgb var, \
Hpoints u (a):(f(a+dx($0),a)):(Hpoints[$0+1]) w p pt var lc rgb Hcolor(NaN)
unset multiplot
### end of code
Result:
I created the following datafile (mind the two empty lines):
-2 0 0 1
0 0 2 1
0 0 0 1
and ran the following gnuplot commands:
set yrange [-2:2]
plot "file" using 1:2 with lines,\
"" using 3:4 with lines, \
"" index 1 using 1:2 with points pointtype 6, \
"" index 1 using 3:4 with points pointtype 7
Fix the colours to your liking.

Separate key (legend) for colors and markers

I have a plot with several types of objects (each read from a separate file). I'm plotting the same several functions for all of them, all on the same graph (same X-axis).
I set the markers (pt) explicitly for each, and the color (lc), so the same object has the same marker, but the same function has the same color. As an example we have 2 files, one for each object (| is just to separate the files here):
0 0 0 | 0 1 1
1 1 2 | 1 1 2
Let's call the left file A, the right B. Column 1 in each file is the x axis, column 2 is using 1:2, and column 3 is using 1:3. So using the above files in an interactive session:
gnuplot> plot "A" using 1:2 with lp pt 1 lc 'black'
gnuplot> replot "A" using 1:3 with lp pt 1 lc 'red'
gnuplot> replot "B" using 1:2 with lp pt 2 lc 'black'
gnuplot> replot "B" using 1:3 with lp pt 2 lc 'red'
we get:
Is it possible to have the key separated, so A/B appear next to their respective marker, and the function name ("using...") appears next to a line (or anything) with the appropriate color?
Right now by omitting titles (notitle in the plot command) I can get one or the other, though I would have to settle on some uniform arbitrary marker/color (depending on what I chose to set as key). Can I:
Get two keys somehow? - Preferably setting the missing attribute (color or marker) to something not in the plot.
If not, can I customize a manual legend somehow?
I am not fully sure what you want to achieve, nevertheless as for the splitting of the key, I don't think that Gnuplot has some "out-of-the-box" feature for this. However, you could (ab)use multiplot to achieve this effect. The idea is basically to generate two overlapping plots - one with points and one with lines - and to position the keys independently:
set terminal pngcairo rounded font ",16"
set output 'fig.png'
$A << EOD
0 0 0
1 1 2
EOD
$B << EOD
0 1 1
1 1 2
EOD
set multiplot
set xtics out nomirror
set ytics out nomirror
eps = 0.1
set lmargin at screen eps
set rmargin at screen 1 - eps/2
set bmargin at screen eps
set tmargin at screen 1 - eps/2
#common key settings
set key left top Left reverse spacing 1.5
set key at screen 0.1,screen 1-eps
plot \
$A u 1:2 with p ps 1.5 pt 1 lc 'black' t 'A', \
$A u 1:3 with p ps 1.5 pt 1 lc 'red' t 'A' , \
$B u 1:2 with p ps 1.5 pt 2 lc 'black' t 'B', \
$B u 1:3 with p ps 1.5 pt 2 lc 'red' t 'B'
unset border; unset xtics; unset ytics
set key at screen 0.3,screen 1-eps
plot \
$A u 1:2 with l lc 'black' t 'using 1:2', \
$A u 1:3 with l lc 'red' t 'using 1:3', \
$B u 1:2 with l lc 'black' t '', \
$B u 1:3 with l lc 'red' t ''
This would give you:

Point color in gnuplot 4.0

When I try to plot three separate data files using gnuplot, I get an error "';' expected" in the output when I try to change the point color of the data sets.
For example, this works fine:
set terminal jpeg size 900,500
set xlabel 'x axis label'
set ylabel 'y axis label'
set title 'sample title'
set output "output.jpeg"
set xrange [-0.1:1.1]
set yrange [] reverse
set xtics 0.10
#set ytics 100
set key top left
set grid ytics lt 0 lw 1
set grid xtics lt 0 lw 1
plot 'file1.dat' u 1:2 w p pt 7 ps 0.8 ti 'dataset 1', \
'file2.dat' u 1:2 w p pt 6 ps 0.8 ti 'dataset 2', \
'file3.dat' u 1:2 w p pt 5 ps 0.8 ti 'dataset 3'
This does not:
set terminal jpeg size 900,500
set xlabel 'x axis label'
set ylabel 'y axis label'
set title 'sample title'
set output "output.jpeg"
set xrange [-0.1:1.1]
set yrange [] reverse
set xtics 0.10
#set ytics 100
set key top left
set grid ytics lt 0 lw 1
set grid xtics lt 0 lw 1
plot 'file1.dat' u 1:2 w p pt 7 ps 0.8 lc 9 ti 'dataset 1', \
'file2.dat' u 1:2 w p pt 6 ps 0.8 ti 'dataset 2', \
'file3.dat' u 1:2 w p pt 5 ps 0.8 ti 'dataset 3'
Why is this? Is there a workaround to simply change point color independent of point style and size?
Thanks!
The keyword linecolor (lc) was introduced in version 4.2. In your case you can change the color using linetype (lt):
set terminal jpeg size 900,500
set output "output.jpeg"
plot 'file1.dat' u 1:2 w p pt 7 ps 0.8 lt 9 ti 'dataset 1'
But I also strongly recommend you to upgrade!

Thicker lines in the legend of gnuplot

I'm plotting some data curves with gnuplot, and they look like this:
However, the line samples in the legend are too thin. When you have more curves, it becomes hard to distinguish the colors. You can increase the thickness of the curves using "linewidth", e.g., by adding "lw 3" to the plot command, and you'd get this:
However, this increases the thickness everywhere. Is it possible to make the lines thick in the legend only? I know it can be done "the other way", by postprocessing on the output .png file. But is there a direct approach, using some gnuplot setting/wizardry?
Unfortunately, I don't know a way to control the thickness of the lines in the key, since they correspond to the lines being drawn. You can see what you can change by typing help set key in gnuplot.
Using multiplot, you can draw the plot lines first without the key, then draw the key again for 'ghost lines'. Here is a code sample which would do that:
set terminal png color size 800,600
set output 'plot.png'
set multiplot
unset key
plot '../batteries/9v/carrefour.txt' w lp, \
'../batteries/9v/philips.txt' w lp, \
'../batteries/9v/sony.txt' w lp
set key; unset tics; unset border; unset xlabel; unset ylabel
plot [][0:1] 2 title 'Carrefour' lw 4, \
2 title 'Philips' lw 4, \
2 title 'Sony' lw 4
In the second plot command, the function 2 (a constant) is being plotted with a y range of 0 to 1, so it doesn't show up.
I ran across this post and it gave me a critical idea.
The provided solution does not work in multiplot mode, since the second plot command will trigger the second plot, which is most likely not desired.
as a workaround one can set the original data as "notitle", then plot data outside of range with the same linetype and color in different thickness with the desired title. I'll just leave my current example here. It also includes linestyles that i have declared. So i just use the same linestyle (ls) to get the same color but change the thickness on the second line.
# for pngs
set terminal pngcairo size 1600,600 font ',18' enhanced
set output "pic_multi_kenngr_ana.png
set style line 2 lc rgb '#0ce90b' lt 1 lw 1.5 # --- green
set style line 3 lc rgb '#09e0b3' lt 1 lw 1.5 # .
set style line 4 lc rgb '#065fd8' lt 1 lw 1.5 # .
set style line 5 lc rgb '#4e04cf' lt 1 lw 1.5 # .
set style line 6 lc rgb '#c702a9' lt 1 lw 1.5 # .
set style line 7 lc rgb '#bf000a' lt 1 lw 1.5 # --- red
set multiplot layout 1,2
set xtics rotate
set tmargin 5
set xtics 12
set grid xtics
# set axis labels
set ylabel 'T [K]'
set xlabel 'Zeit [h]'
# select range
set xrange [0:48]
set yrange [290.15:306.15]
set title "(a) Bodentemperatur"
set key top right Right
plot 'par_crank_hom01lvls.04.dat' u 1:3 with lines ls 7 notitle,\
'par_crank_str01lvls.16.dat' u 1:3 with lines ls 2 notitle,\
500 t 'z = 4 cm' ls 7 lw 4,\
500 t 'z = 16 cm' ls 2 lw 4
################################################
set title "(b) Bodenwärmestrom an der Oberfläche"
set ylabel 'G [W m^{-2}]'
set yrange[-110:110]
unset key
plot 'par_crank_str01_ghf.dat' u 1:3 with lines
unset multiplot
I hope this will help someone
An even more simple work-around (imho) is to define the colours explicitly and plot each line twice, once with high lw for the key and also with the title to appear in the key, but adding "every ::0::0" which effectively ends up in plotting nothing, and once the normal way. See the following code snippet:
plot data u 0:1 w l linecolor rgb #1b9e77 lw 2 t "",\
data every ::0::0 u 0:1 w l linecolor rgb #1b9e77 lw 4 t "Title"
To expand on the NaN comment by #Svalorzen, the following will graph two lines of width 1 from some datafile.txt with no titles and create matching blank lines with the specified titles and width 5 for the key only:
plot [][]\
NaN title "Title1" w line lt 1 lc 1 lw 5,\
NaN title "Title2" w line lt 1 lc 2 lw 5,\
"datafile.txt" using 1:2 title "" w line lt 1 lc 1 lw 1,\
"datafile.txt" using 1:3 title "" w line lt 1 lc 2 lw 1
I find an answer for this:
Set key linewidth
in your case, must be:
plot '../batteries/9v/carrefour.txt' w l lw 1 linetype 1 notitle, 0/0 linetype 1 linewidth 5 title 'Carrefour'
rep '../batteries/9v/philips.txt' w l lw 1 linetype 2 notitle, 0/0 linetype 2 linewidth 5 title 'Philips'
rep '../batteries/9v/sony.txt' w l lw 1, linetype 3 notitle, 0/0 linetype 3 linewidth 5 title 'Sony'
Try something like:
plot # ... \
keyentry w l lw 1 lc 2 t "Title" # ...
And remove the old keys.

Resources