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

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

Related

Bubble graphs - how to use?

Is it possible to combinate "normal points" and "bubble points"? I have two sets of data - file1.txt and file2.txt and for one of them (file2.txt) I would like to use points like http://gnuplot-tricks.blogspot.com/2009/06/
How to compose this into code please? When I use the code from that webpage how to plot another data. I tried this:
f(x) = A*exp(-x*x/B/B)
rx=0.107071; ry=0.057876; A = 1; B = 0.2; C=0.5*rx; D=-0.4*ry
g(u,v) = (2*cos(u)*v*rx+C)*(2*cos(u)*v*rx+C)+(3.5*sin(u)*v*ry+D)*(3.5*sin(u)*v*ry+D)
unset key; unset colorbox; set view map
set xrange [-0.15:5.2]; set yrange [-0.7:0.95]
set parametric; set urange [0:2*pi]; set vrange [0:1]
set isosamples 20, 20; set samples 30
set palette model HSV functions 1, 1-f(gray), 1+2*f(gray)
splot cos(u)*rx*v-0.13335347,sin(u)*ry*v+2.7730389, g(u,v) w pm3d, \
cos(u)*rx*v-0.11625481,sin(u)*ry*v+3.5312312, g(u,v) w pm3d, \
cos(u)*rx*v-0.14454222,sin(u)*ry*v+3.6412394, g(u,v) w pm3d, \
cos(u)*rx*v-0.070272446,sin(u)*ry*v+3.8070912, g(u,v) w pm3d, \
cos(u)*rx*v-0.10077238,sin(u)*ry*v+4.090774, g(u,v) w pm3d, \
'file1.txt' using 2:1:(0.0):2 with points pt 7 ps 1 palette
but file2 is not splot. Thank you very much
Here is a variant of the "trick" shown in your second link. I have extracted the customized point styles into a pre-defined set of linetypes. This makes the plot command itself simpler, and it is easier to reuse the definitions in multiple plots.
set linetype 101 ps 3.0 pt 7 lc rgb "#ff0000"
set linetype 102 ps 2.6 pt 7 lc rgb "#ff2222"
set linetype 103 ps 2.2 pt 7 lc rgb "#ff4444"
set linetype 104 ps 1.8 pt 7 lc rgb "#ff6666"
set linetype 105 ps 1.4 pt 7 lc rgb "#ff8888"
set linetype 106 ps 1.0 pt 7 lc rgb "#ffaaaa"
set linetype 107 ps 0.6 pt 7 lc rgb "#ffcccc"
set linetype 108 ps 0.2 pt 7 lc rgb "#ffeeee"
set border back
plot for [LT=101:108] 'silver.dat' using 1:2 with point lt LT notitle
Please clarify what exactly what properties your plot needs to have.
(1) The term "bubble plot" usually refers to a plot in which each point is drawn as a circle with additional properties encoded by changing the size, color, or other property of the circle. Gnuplot can do that quite well. A good example can be found in the online demo collection: Hypertext bubble chart In this case the size of the circle is used to indicate relative population and additional information is encoded as hypertext (pop-up text box) attached to that point. Variable color could easily be added as well. The png version below does not include the hypertext.
(2) The example you link in the query does not appear to encode any additional information into the shape or color of the point but it does use a fancy glyph for each point rather than a simple dot or cross. Gnuplot can do that also. It depends on exactly what set of symbols or glyphs you want to use. If you can find a font providing appropriate glyphs then one way is shown here:
shape(i) = (i%4 == 0) ? "βŠ•" : (i%4 == 1) ? "βŠ™" : (i%4 == 2) ? "⊚" : "β¦Ύ"
set grid x y z vertical
splot 'silver.dat' using 1:2:3:(shape(int(column(0))) with labels textcolor "forest-green"
More complicated options are also possible but may depend on exactly what you need and what output format (gnuplot "terminal type") is acceptable.

gnuplot histogram chart with overlap

I would like to plot a bar chart or histogram like this in gnuplot.
I tried set style histogram rowstacked which is a start but it adds the columns on top of each other while I need them overlapped. Next is the issue of transparent color shading.
Thanks for your feedback.
UPDATE: user8153 asked for additional data.
The set style histogram clustered gap 0.0 is doing the cluster mode of the histogram bars. If you blur the eye it sort-of shows what I want but with overlap and transparent shading.
The only other histogram modes given in the docs are rowstacked and columnstacked. I never got a plot out of columnstacked so I discarded it. Now rowstacked stacks the histogram bars.
The overlay appearance is there but it is wrong. I don't want the stacked appearance. The histograms have to overlay.
Code :
set boxwidth 1.0 absolute
set style fill solid 0.5 noborder
set style data histogram
set style histogram clustered gap 0.0
#set style histogram rowstacked gap 0.0
set xtics in rotate by 90 offset first +0.5,0 right
set yrange [0:8000]
set xrange [90:180]
plot 'dat1.raw' using 3 lc rgb 'orange', \
'dat2.raw' using 3 lc rgb 'blue', \
'dat3.raw' using 3 lc rgb 'magenta'
Thanks for your feedback.
Given a sample datafile test.dat
-10 4.5399929762484854e-05
-9 0.0003035391380788668
-8 0.001661557273173934
-7 0.007446583070924338
-6 0.02732372244729256
-5 0.0820849986238988
-4 0.20189651799465538
-3 0.4065696597405991
-2 0.6703200460356393
-1 0.9048374180359595
0 1.0
1 0.9048374180359595
2 0.6703200460356393
3 0.4065696597405991
4 0.20189651799465538
5 0.0820849986238988
6 0.02732372244729256
7 0.007446583070924338
8 0.001661557273173934
9 0.0003035391380788668
10 4.5399929762484854e-05
you can use the following commands
set style fill transparent solid 0.7
plot "test.dat" with boxes, \
"test.dat" u ($1+4):2 with boxes
to get the following result (using the pngcairo terminal):
Using transparency as in user8153's solution is certainly the easiest way to visualize an overlap of two histograms.
This works even if the two histogram do not have identical bins or x-data-ranges.
However, the color of the overlap is pretty much bound to the colors of the two histogram and the level of transparency. Furthermore, if you want to show the overlap in the key you have to do it "manually".
Here is a solution where you can choose an independent color for the overlap area.
The overlap is basically the minimum y-value from both histograms for each x-value.
For this you need to compare the y-values for each x-value. This can be done in gnuplot with some "trick" by merging the two files line by line. This requires the data in a datablock (how to get it there from a file). Since this merging procedure is using indexing of datablock lines, it requires gnuplot>=5.2.0.
This assumes that you have the same x-range and bins for each histogram. If this is not the case, you have to implement some further steps.
Script: (works with gnuplot>=5.2.0, Sept. 2017)
### plot overlap of two histograms
reset session
# create some random test data
set samples 21
f(x,a,b) = 1./(a*(x-b)**4+1)
set table $Data1
plot '+' u 1:(f(x,0.01,-2)) w table
set table $Data2
plot '+' u 1:(f(x,0.02,4)) w table
unset table
set boxwidth 1.0
set grid y
set ytics 0.2
set multiplot layout 2,1
set style fill transparent solid 0.3
plot $Data1 u 1:2 w boxes lc 1 ti "Data1", \
$Data2 u 1:2 w boxes lc 2 ti "Data2"
set print $Overlap
do for [i=1:|$Data1|] { print $Data1[i].$Data2[i] }
set print
set style fill solid 0.3
plot $Data1 u 1:2 w boxes lc 1 ti "Data1", \
$Data2 u 1:2 w boxes lc 2 ti "Data2", \
$Overlap u 1:($2>$4?$4:$2) w boxes lc "red" ti "Overlap"
unset multiplot
### end of script
Result:

gnuplot: selectively put certain keys to the top

I am trying to use gnuplot to draw a figure. Due to the limited space, the figure is drawn like this:
I am thinking to move the first three labels (ins-replace, bb-split and func-reorder to the top of the figure, outside!)
So it should be something like this :
set key outside
But basically how to select the first three keys and move them to the outside? Is it possible to do so?
I put my script here:
set term pdf size 10,8 font "Arial,44"
set output "plot/bzip-ropbase-mix.pdf"
set size ratio 0.6
#set multiplot layout 1,1
set datafile separator ","
set offset 0, 0, 0, 0
set xtics norangelimit
set ytics nomirror
set termoption dashed
set ylabel "Gagdet Elimination Rate (%)"
set xlabel "Iteration"
set key bottom right
set yrange [0:110]
set style data linespoints
set key vertical maxrows 5
plot 'plot/bzip-ropbase-data.csv' using 11:xtic((int($0)%4)==0? sprintf("%d", $0*50):"") title columnheader(11) pt 4 lw 1, \
'' using 12 title columnheader(12) pt 5 lw 4 ps .8 lc rgb "#4169E1", \
'' using 13 title columnheader(13) pt 6 lw 4 ps .8 lc rgb "#DAA520", \
'' using 14 title columnheader(14) pt 7 lw 4 ps .8 lc rgb "#FF7F50", \
'' using 15 title columnheader(15) pt 8 lw 4 ps .8 lc 7
Could anyone give me some help? Thank you!
You cannot do this automatically but there are ways around it. The first one to come to mind is to use multiplot, then plot first all the functions and files whose title you want outside and then all of those that you want inside. You'll need to disable drawing borders etc. for the first instance and then enable it for the second instance. To make sure your plotting area remains constant during the two plot instances you'll need to hard set the margins:
set multiplot
set xrange [0:2.*pi]
# Set the margins
set lmargin at screen 0.1; set rmargin at screen 0.98
set tmargin at screen 0.8; set bmargin at screen 0.1
# Disable drawing borders and tics
unset border; unset tics
# Set position of the legend
set key tmargin
# Draw the first batch of stuff
plot cos(x) lc 1
# Enable drawing borders and tics
set border; set tics
# Set position of the legend
set key inside
# Draw the second batch of stuff
plot sin(x) lc 2

Custom legend (or text) gnuplot

I have a file with 3 columns, the first 2 are the position x y and the 3rd one I use it for define the color so I have something like this:
set palette model RGB defined ( 1 'black', 2 'blue', 3 'green', 4 'red')
unset colorbox
plot "file" u 2:1:3 w points pt 14 ps 2 palette, "file2" u 2:1:3 w points pt 14 ps 2 palette
Now the question: Is it possible to have a proper legend with this kind of point and COLOR?.
Since the points will have different colors (according to the pallete) I want to specify what means each color in the legend.
The only solution I was thinking was to write somewhere in the plot some text with the character of the point (in this case pt 14) and specify the color... but is not really a solution right?
So please help!
There is no option for this, you need to fiddle a bit. Here is YAGH (Yet another gnuplot hack) ;)
Assuming that your values are equidistantly spaced, you can use the '+' special filename with the labels plotting style.
To show only the custom key, consider the following example:
labels="first second third fourth"
set xrange[0:1] # must be set for '+'
set yrange[0:1]
set samples words(labels) # number of colors to use
key_x = 0.8 # x-value of the points, must be given in units of the x-axis
key_y = 0.8
key_dy = 0.05
set palette model RGB defined ( 1 'black', 2 'blue', 3 'green', 4 'red')
unset colorbox
plot '+' using (key_x):(key_y + $0*key_dy):(word(labels, int($0+1))):0 \
with labels left offset 1,-0.1 point pt 7 palette t ''
This gives (with 4.6.4):
As the set samples doesn't affect the data plots, you can integrate this directly in your plot command:
...
unset key
plot "file" u 2:1:3 w points pt 14 ps 2 palette, \
"file2" u 2:1:3 w points pt 14 ps 2 palette, \
'+' using (key_x):(key_y - $0*key_dy):(word(labels, int($0+1))):0 \
with labels left offset 1,-0.1 point pt 14 ps 2 palette
But you need to set a proper xrange, yrange and the values of key_x, key_y and key_dy.
This is not the most intuitive way, but it works :)
I have an alternative solution posted here:
Using Gnuplot to plot point colors conditionally
Essentially you plot once without a legend entry, then make dummy plots (with no data) for each point color/label.

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

Resources