Gnuplot key: Force uneven split - gnuplot

I have four curves to plot. The first three are variants of each other, the fourth one is distinct. Hence, I would like the key to split in 3+1. However, using e.g.
set key maxrows 3
plot sin(x),sin(2*x),sin(3*x),exp(x)
gives a two-row key.
Can I force gnuplot to split the key in three+one?

In addition to #user8153's solution, I would like to suggest a slightly more general solution.
What if you have a colored background? For example: set term wxt background rgb "grey90" or if
you have a colored key (or legend) box... hmm, well, gnuplot doesn't offer an option for
colored background of the key box. Well, then if you put a colored rectangle behind the key.
Of course you can always adapt the color to the background, but I guess it would be simpler to plot an invisible line with lt -2 or lt nodraw.
About lt -2 or lt nodraw, I just learned a few days ago here: gnuplot: why is linewidth 0 not zero in width?. It's not (yet) in the manual, although it seems to be around since gnuplot version 5.0.
Code:
### invisible keyentry for column/row arrangement
reset session
set key top left maxrows 3
set obj 1 rect from graph 0.02,0.82 to graph 0.52,0.98 fs solid 1.0 fc rgb "grey90"
set xrange[-2:2]
set yrange[-2:2]
plot sin(x), sin(2*x), sin(3*x), exp(x), NaN lt -2 ti " "
### end of code
Result:
Addition:
Actually, I forgot that there is a workaround for a colored background of the keybox. No manual adjustment and fiddling around with the box:
Set custom background color for key in Gnuplot
In case you want a transparent background, e.g. for images on webpages using, e.g. pngcairo, pdfcairo, etc., besides lt -2 or lt nodraw, another solution would be to plot a transparent line, e.g. transparent "black" lc rgb 0xff000000:
plot sin(x), sin(2*x), sin(3*x), exp(x), NaN lc rgb 0xff000000 ti " "
Code:
### invisible keyentry for column/row arrangement with transparent background
reset session
set term pngcairo transparent
set output "tbKeyRows.png"
set key top left maxrows 3
set xrange[-2:2]
set yrange[-2:2]
plot sin(x), sin(2*x), sin(3*x), exp(x), NaN lt -2 ti " "
set output
### end of code
Result: (shown in front of checkerboard pattern)

Related

gnuplot and "extra" graphics objects (like a dot or circle) in any general location on plot (e.g. in the "title" area)

Consider the following example script :
reset session
set multiplot layout 1,2
set title "."
plot sin(x)
set title "."
plot sin(x**2)
unset multiplot
... one can see that the set title "." is a kludge for, ideally, a nicer dot - perhaps what is called a "bulletpoint". While I could pursue this kludge, using O, or other font sizes, point sizes, or {/Symbol } (in progress), or terminals of the LaTeX variety (because there are pretty good mathematical symbols I could use like cdot), it would be interesting to know in general - a simple shape like a dot or square, imposed somewhere on the plot, but outside the usual set title or label which have certain rules with the fonts and such.
It's still not fully clear to me what you want to achieve. Placing a point which tunable size as title or at the place where the title usually would be?
You can use set label with option point (check help label). You can set different point types, type test in the gnuplot console to see the available pointtypes. It's not clear, why you wrote that you don't want to use labels. Maybe with the example below we'll get a step further.
Script:
### place a point somewhere on the canvas
reset session
set multiplot layout 1,2
set title "."
plot sin(x)
set title " "
set label 1 at graph 0.2,1.05 point pt 7 ps 0.25 lc "dark-violet"
set label 2 at graph 0.3,1.05 point pt 7 ps 0.50 lc "blue"
set label 3 at graph 0.4,1.05 point pt 7 ps 0.75 lc "cyan"
set label 4 at graph 0.5,1.05 point pt 7 ps 1.00 lc "green"
set label 5 at graph 0.6,1.05 point pt 7 ps 1.25 lc "yellow"
set label 6 at graph 0.7,1.05 point pt 7 ps 1.50 lc "orange"
set label 7 at graph 0.8,1.05 point pt 7 ps 1.75 lc "red"
plot sin(x**2)
unset multiplot
### end of script
Result:
You can place a graphical object (drawn with vectors and/or solid fill) using the command set object {circle|rectangle|polygon} at .... See User Manual or interactive help for details.
You can use any unicode character including math symbols and even emojis in a title or label. Yes, you must have a font available that contains that character, but these days that is not much of a limitation. For example:
set title "Various solar symbols: ☀☼🌣☉"
Even if you have trouble entering the desired symbol via keyboard or cut-and-paste, current gnuplot allows you to specify the unicode symbol as an escape sequence:
set label 1 "Solar symbol" at graph 0.5, 1.0 point pointtype "\U+2609"
set border 3; unset tics
plot 1/exp(x) notitle
I gathered these approaches in a demonstration script the sin(x) functions are just for show :
reset session
unset key
#
set grid x,y
set style fill solid 1.0
set multiplot layout 2,2
#
set title "."
plot 1*sin(x)
unset title
#
set title "O"
plot 2*sin(x)
unset title
unset object
#
# series of objects
# only valid on on the specific plot area
# not outside the e.g. axes or border
set object circle at 1,1
set object circle at 1,2
set object circle at 1,3
plot 3*sin(x)
unset object
#
set label 1 at graph -0.1,1.10 point pt 7 ps 1.00 lc "black"
set label 2 at graph 0.0,1.10 point pt 7 ps 1.00 lc "black"
set label 3 at graph 0.5,1.05 point pt 7 ps 1.00 lc "black"
set label 4 at graph 0.5,1.10 point pt 7 ps 1.00 lc "black"
plot 4*sin(x)
unset label
#
unset multiplot
unset output
I couldn't get fill style solid 1.0 to work on set object circle the way I wanted so I left it, perhaps there is a way. One can see the circle gets cut off on the edge. The label coordinates also have requirements (see manual).
To be clear, I am writing this "answer" but the question is only "answered" because of theozh and Ethan (thanks!).

Set title for arrow in gnuplot

I've used the arrow to draw a vertical line and I would like to title it so it's shown in the key. Is there a way to do it? As far as I can tell for the manual, there's no title option in the syntaxis for arrow, but I'm sure there's a workaround.
The only thing I think of is drawing the arrow with the same color as something outside the plot range and use its title, but it's rather clumsy.
I'm using the terminal pngcairo, just in case it's relevant.
You can plot something with vectors, which will give a title in the key. It plots arrows based on data points. The using statement is x:y:Δx:Δy where the tail is positioned at (x, y) and the head is at (x+Δx, y+Δy). For a vertical line, you can turn off the arrow head and use Δx of zero:
set terminal pngcairo dashed
set output 'plot.png'
set angles degrees
set xrange [0:360]
set yrange [-2:2]
plot sin(x), '-' using 1:(-2):(0):(4) with vectors nohead lc rgb 'black' title '90 degrees'
90
e
Gnuplot will ignore anything with an invalid value (1/0 for instance). You can take advantage of this to plot what you want.
Suppose that we set a vertical line with
set arrow from 1,graph 0 to 1,graph 1 nohead lt 0
Now, if I want this to be in the key, I can just plot a line with lt 0 but specify the y-value as 1/0. This will insert it in the key, but will not actually draw the line.
plot [-3:3] x**2 t "X Squared", 1/0 t "Vertical Line" lt 0

Gnuplot histogram gap does nothing

I have a gnuplot script which plots a histogram. I used the following syntax:
set style data histogram
set style histogram cluster gap 2
set style fill solid
set logscale y
rgb(r,g,b) = int(r)*65536 + int(g)*256 + int(b)
plot 'histogram_data' using (column(0)):2:(0.5):(rgb($3,$4,$5)):xticlabels(1) w boxes notitle lc rgb variable
What the last line does is: using column 1 as x labels, column 2 as the height of the histogram bars, 0.5 as box width, and columns 3, 4 and 5 as the rgb values to colour the bars.
Now, the problem is that modifying the gap parameter in line 2 does not change in any way the spacing between bars, even though as far as I understand that is the correct way to adjust such spacing. I am using gnuplot 4.6 patchlevel 4.
I found a way to do this with boxes, though I do not consider it very clean:
plot 'histogram_data' u (column(0)*2+1):2 w boxes notitle lc rgb 'white',\
'histogram_data' u (column(0)*2):2:(rgb($3,$4,$5)):xticlabels(1) w boxes notitle lc rgb variable;
This command is plotting all the data of the main plot on even slots and a white box on odd slots. So the first line in the plot command is plotting the gaps between every box of the plot (the width of these gaps can be specified using the boxwidth property I think but I haven't tested this), while the second line is drawing the actual plot.
I could not find a way to do this with the histogram plotting style, keeping the variable colours specified in the data file.

Add a single point at an existing plot

I am using the following script to fit a function on a plot. In the output plot I would like to add a single value with etiquette on the fitting curve lets say the point f(3.25). I have read that for gnuplot is very tricky to add one single point on a plot particularly when this plot is a fitting function plot.
Has someone has an idea how to add this single point on the existing plot?
set xlabel "1000/T (K^-^1)" font "Helvetica,20"
#set ylabel "-log(tau_c)" font "Helvetica,20"
set ylabel "-log{/Symbol t}_c (ns)" font "Helvetica,20"
set title "$system $type $method" font "Helvetica,24"
set xtics font "Helvetica Bold, 18"
set ytics font "Helvetica Bold, 18"
#set xrange[0:4]
set border linewidth 3
set xtic auto # set xtics automatically
set ytic auto # set ytics automatically
#set key on bottom box lw 3 width 8 height .5 spacing 4 font "Helvetica, 24"
set key box lw 3 width 4 height .5 spacing 4 font "Helvetica, 24"
set yrange[-5:]
set xrange[1.5:8]
f(x)=A+B*x/(1000-C*x)
A=1 ;B=-227 ; C=245
fit f(x) "$plot1" u (1000/\$1):(-log10(\$2)) via A,B,C
plot [1.5:8] f(x) ti "VFT" lw 4, "$plot1" u (1000/\$1):(-log10(\$2)) ti "$system $type" lw 10
#set key on bottom box lw 3 width 8 height .5 spacing 4 font "Helvetica, 24"
set terminal postscript eps color dl 2 lw 1 enhanced # font "Helvetica,20"
set output "KWW.eps"
replot
There are several possiblities to set a point/dot:
1. set object
If you have simple points, like a circle, circle wedge or a square, you can use set object, which must be define before the respective plot command:
set object circle at first -5,5 radius char 0.5 \
fillstyle empty border lc rgb '#aa1100' lw 2
set object circle at graph 0.5,0.9 radius char 1 arc [0:-90] \
fillcolor rgb 'red' fillstyle solid noborder
set object rectangle at screen 0.6, 0.2 size char 1, char 0.6 \
fillcolor rgb 'blue' fillstyle solid border lt 2 lw 2
plot x
To add a label, you need to use set label.
This may be cumbersome, but has the advantage that you can use different line and fill colors, and you can use different coordinate systems (first, graph, screen etc).
The result with 4.6.4 is:
2. Set an empty label with point option
The set label command has a point option, which can be used to set a point using the existing point types at a certain coordinate:
set label at xPos, yPos, zPos "" point pointtype 7 pointsize 2
3. plot with '+'
The last possibility is to use the special filename +, which generates a set of coordinates, which are then filtered, and plotted using the labels plotting style (or points if no label is requested:
f(x) = x**2
x1 = 2
set xrange[-5:5]
set style line 1 pointtype 7 linecolor rgb '#22aa22' pointsize 2
plot f(x), \
'+' using ($0 == 0 ? x1 : NaN):(f(x1)):(sprintf('f(%.1f)', x1)) \
with labels offset char 1,-0.2 left textcolor rgb 'blue' \
point linestyle 1 notitle
$0, or equivalently column(0), is the coordinate index. In the using statement only the first one is taken as valid, all other ones are skipped (using NaN).
Note, that using + requires setting a fixed xrange.
This has the advantages (or disadvantages?):
You can use the usual pointtype.
You can only use the axis values as coordinates (like first or second for the objects above).
It may become more difficult to place different point types.
It is more involved using different border and fill colors.
The result is:
Adding to Christoph's excellent answers :
4. use stdin to pipe in the one point
replot "-" using 1:(f($1))
2.0
e
and use the method in 3rd answer to label it.
5. bake a named datablock
(version > 5.0) that contains the one point, then you can replot without resupplying it every time:
$point << EOD
2.0
EOD
replot $point using 1:(f($1)):(sprintf("%.2f",f($1))) with labels
6. A solution using a dummy array of length one:
array point[1]
pl [-5:5] x**2, point us (2):(3) pt 7 lc 3
7. Or through a shell command (see help piped-data):
pl [-5:5] x**2, "<echo e" us (2):(3) pt 7 lc 3
pl [-5:5] x**2, "<echo 2 3" pt 7 lc 3
8. Special filename '+'
pl [-5:5] x**2, "+" us (2):(3) pt 7 lc 3
It seems to be the shortest solution. But note that while it looks like a single point, these are like 500 points (see show samples) plotted on the same position.
To have only one point the sampling needs to be temporarily adjusted (see help plot sampling)
pl [-5:5] x**2, [0:0:1] "+" us (2):(3) pt 7 lc 3
9. Function with zero sampling range length
Shortest to type, but plotting as many points on top of each other as many specified with samples
pl [-5:5] x**2, [2:2] 3 w p pt 7 lc 3

bring legend to the front in gnuplot

Is there a way to bring the key (legend) in gnuplot (epslatex terminal) to the very front? In my plot I experience that some filledcurves are on top of the small line samples of the key so that these are invisible. The lables in the key are placed on top as they are drawn by latex. I know that I could change the order in the plot (filledcurves first) but I actually want that the filledcurves hide the previously drawn lines in the plot itself.
Recent gnuplot versions allow you to say "set key opaque", which I think does what you want.
First plot your lines without the key plot x notitle ls 1, then plot your filledcurves, then plot yet the extra lines using the linestyles of the first lines, but so that they are out of the visible area:
set yrange [-10:10]
plot -x notitle ls 2, x**2/3-5 w filledc ls 5, x**2+100 t "first-line legend" ls 2
This gives you the legend at the top of the filledcurves, but the visible lines below. Hope this works with epslatex too.
#sfeam's answer is correct, as long as the key doesn't have overlap with the border. If it has, there's no way to bring the legend in front of the border, but you can bring the border to the back by "set border back".
So, a combination of "set key opaque" and "set border back" guarantees that the legend is on top of everything.
One can use dummy plot-elements with NaN (or keyentry for gnuplot 5.2.6). The key title will not be in front.
Here is a comparison between default, the NaN approach and key opaque.
reset session
set samp 10000
a = 10
set xrange [0:200]
set multiplot layout 2,2
set key title "default"
plot sin(x), cos(x)
set key title "NaNs dummy entries"
plot sin(x) t "", cos(x) t "",\
NaN t "sin(x)" ls 1, NaN t "cos(x)" ls 2
set key opaque title "key opaque"
plot sin(x), cos(x)
unset multiplot

Resources