Exact meaning of dashtype index in the Gnuplot 5.0? - gnuplot

I got a problem in Gnuplot 5.0, the dashtype index, such as ``set dashtype 1 (2,5,2,15)` in the manual.
My question is: what do these numbers in parenthesis exactly mean? I tried to change them to get a feeling, but it would be great to know the exact meaning.
My actual problem is, that simply using dashtype N, gives lines which look very different from the previous 4.6 version, unfortunately. I just try to reproduce the plots which were made in gnuplot 4.6.

Those are numerical pairs
<solid length>,<empty length>
Those lengths are factors for an internal unit length. The dash pattern length further depends on the dashlength terminal option and the line width.
So, having
plot x dt (2,4,2,6)
plots a dash, an empty space twice as long, again a dash of same length and an empty space three times the dash length.
The actual length of the first dash is then
linewidth * terminal_linewidth * solid_length * terminal_dashlength * dash_unit
First example:
set terminal pngcairo size 600,50 dashlength 2 linewidth 1
set output 'dash1.png'
unset border; unset key; unset tics
plot 0 dt (2,4,2,6) lw 10
What might be confusing is, that some terminals like qt or wxt use rounded line ends by default (terminal option round), which are applied to every single dash, which distorts the actually given dash lengths:
set terminal pngcairo size 600,50 round dashlength 2 linewidth 1
set output 'dash2.png'
unset border; unset key; unset tics
plot 0 dt (2,4,2,6) lw 10
Terminal option square extends each dash by one line width at each end:
set terminal pngcairo size 600,50 square dashlength 2 linewidth 1
set output 'dash2.png'
unset border; unset key; unset tics
plot 0 dt (2,4,2,6) lw 10
In this last example, the final dash lengths are (4,2,4,4).
To get the behavior of the first example (exact dash length) also by default with other terminals, use the butt terminal option.

from: http://www.gnuplot.info/gnuplot_cvs.pdf page 37
set dashtype 1 (2,5,2,15)
means: define stype 1 as:
solid 2
empty 5
solid 2
empty 15
(== == )*

Related

translate palette defined to rgb variable

With palette it is easy to create color gradients
set view map
set samp 50,50
set palette defined (0 "blue", 1 "green", 2 "red")
spl "++" us 1:2:1 palette pt 5
Now I would like to apply transparency in vertical direction. The option lc rbg variable supports transparency via the alpha channel (see also here):
spl "++" us 1:2:1:(int(($2+5)/10*255)<<24) lc rgb var pt 5
But how can I translate the palette colors into rgb colors?
A second question: why I get only 10 horizontal rows, albeit I specified 50 in samp?
Easy answer first: When there is 2-dimensional sampling, either automatically from splot or explicitly from plot '++', the number of samples in the first dimension is controlled by set sample and the number of samples in the second dimension is controlled by set isosample.
Now the harder one. In gnuplot versions through the current 5.2.8 you cannot add transparency directly to the palette. You can, however, go through a multi-step process of saving the palette into a file or datablock and then reading it back it as an array of RGB colors. Once you have that array you can add an alpha channel value so that it expresses transparency as well. I will show this process using the datablock created by the command test palette. In older versions of gnuplot you may have to instead use the file created by set print "palette.save"; show palette palette 256;.
# save current palette to a datablock as a list of 256 RGB colors, one per line
set palette defined (0 "blue", 1 "green", 2 "red")
test palette
# print one line to show the format (cbval R G B NTSCval)
print $PALETTE[4]
# Create an array of packed RGB values
array RGB[256]
do for [i=1:256] {
Red = int(255. * word($PALETTE[i],2))
Green = int(255. * word($PALETTE[i],3))
Blue = int(255. * word($PALETTE[i],4))
RGB[i] = Red << 16 | Green << 8 | Blue
}
# Sample from '++' are generated to span ranges on the u and v axes
# I choose 1:256 so that the y coordinates match the range of array indices
set sample 50
set isosample 50
set urange [1:256]
set vrange [1:256]
set xrange [*:*] noextend
set yrange [*:*] noextend
# Now you can use colors stored in the array via colorspec `rgb variable`
# which will also accept an alpha channel in the high bits
plot "++" using 1:2:(RGB[int($2)]) with points pt 5 lc rgb variable
# The final step is to add an alpha channel as a function of y
# Here I go from opaque (Alpha = 0) to 50% transparent (Alpha = 127)
# This works because I know y will run from 1-256
ARGB(y) = RGB[int(y)] + (int(y/2)<<24)
plot "++" using 1:2:(ARGB($2)) with points pt 5 lc rgb variable
Output shown below.
The required command sequence, as you can see, is a mess.
It will be much easier in the next gnuplot release (5.4). The new version will provide a function palette(z) that converts from the current palette directly to a packed RGB value. Note that the palette() function isn't in the -rc1 testing version but will be in -rc2. So in version 5.4 all that palette/array/RGB manipulation can be replaced by
plot '++' using 1:2:(palette($2) + (int($2)<<24)) with points pt 5 lc rgb variable
Check also this: Gnuplot: transparency of data points when using palette
First of all, you can check what your defined palette is doing:
set palette defined (0 "blue", 1 "green", 2 "red")
test palette
You will get this:
Each channel (R,G,B) has a function with an input range [0:1] and an output range [0:1]. In this case it is a linear gradient.
So, you have to define such a function and put the channels together with the transparency (alpha) channel using the bit shift (see help operators binary).
The nice thing about a palette is that gnuplot takes care about the range. Here, you have to know minimum and maximum in advance and scale the color accordingly. You could use stats for this.
Code:
### your own palette with transparency
reset session
r(x) = x < 0.5 ? 0 : 2*x -1
g(x) = x < 0.5 ? 2*x : 2-2*x
b(x) = x < 0.5 ? 1-2*x : 0
a(y) = y
myColor(x,y) = (int(a((y-yMin)/(yMax-yMin))*0xff)<<24) + \
(int(r((x-xMin)/(xMax-xMin))*0xff)<<16) + \
(int(g((x-xMin)/(xMax-xMin))*0xff)<<8) + \
int(b((x-xMin)/(xMax-xMin))*0xff)
set samples 50
set isosamples 50
set size square
xMin=-5; xMax=5
yMin=-5; yMax=5
plot '++' u 1:2::(myColor($1,$2)) w p pt 5 ps 0.5 lc rgb var notitle
### end of code
Result:

Gnuplot Vertical Dashed Line

I would like to add a gray dashed vertical line on my graph with GNUPLOT.
My terminal is;
set terminal postscript portrait enhanced color dashed lw 1 "DejaVuSans" 12 size 6,6
set output "pic.ps"
set xrange [30:110]
plot 'smth.txt' w lines ls 7 t ""
I have looked into several ideas around but there seems to no explanation about how to get a dashed gray line vertically at let's say x = 40 (the line gonna be parallel to y-axis)
The key is to use the set arrow command and remove the head to make it a line:
set arrow from 40,0 to 40,100 nohead lc rgb 'red' dt 2
Your graph does not specify any y value, so adjust it to a "larger than needed" value.
For dash type (dt), checkout p.42 of manual. It is terminal-dependent (I didn't tried with postscript), but you can adjust as needed.

How to make dashed grid lines intersect making crosshairs in gnuplot?

I'm plotting some data and I want to use dashed grid lines.
Any dashed grid line would suffice, but I prefer a "long dash, short dash, long dash" format.
For example, given the following code
set grid lc rgb "#000000" lt 1 dt (50, 25, 20, 25)
plot x**2
I get this result
But I would rather the grid lines intersection to happen always at the middle of two dashes, like this
If I could make horizontal grid lines different to vertical grid lines and I could add some offset to each one, then I'd imagine there's a way to accomplish this. But I can't seem to do that either.
It looks like gnuplot cannot have two different dashstyles for x-grid and y-grid.
One workaround I see currently is to plot two identical plot on top of each other. One with appropriate x-grid lines and the other with appropriate y-grid lines.
If you want a dash pattern with proportions of (50-25-20-25), this correspond to (25-25-20-25-25-0) or (5-5-4-5-5-0) between two tics.
Furthermore, the dash and gap length numbers, e.g. in dt (50,25,20,25), seem to be in a fixed relation to the graph size. The "empirical" factor is 11 with good approximation (at least for the wxt terminal which I tested under gnuplot 5.2.6).
Edit: actually, the code below gives different results with a qt terminal. And it's not just a different factor. It's more complicated and probably difficult to solve without insight into the source code. So, the fact that the following seems to work with wxt terminal (maybe even just under Windows?) was probably a lucky strike.
With this you can create your dash lines automatically resulting in crosshairs at the intersections of the major grid lines.
Assumptions are:
your first and last tics are on the borders
you know the number of x- and y-intervals
You also need to know the graph size. These values are stored in the variables GPVAL_TERM..., but only after plotting. That's why you have to replot to get the correct values.
This workaround at least should give always crosshairs at the intersection of the major grid lines.
Edit 2: just for "completeness". The factors to get the same (or similar) looking custom dashed pattern on different terminals varies considerably. wxt approx. 11, qt approx. 5.6, pngcairoapprox. 0.25. This is not what I would expect. Furthermore, it looks like the factors slightly depend on x and y as well as graph size. In order to get "exact" crosshairs you might have to tweak these numbers a little further.
Code:
### dashed grid lines with crosshairs at intersections
reset session
TERM = "wxt" # choose terminal
if (TERM eq "wxt") {
set term wxt size 800,600
FactorX = 11. # wxt
FactorY = 11. # wxt
}
if (TERM eq "qt") {
set term qt size 800,600
FactorX = 5.58 # qt
FactorY = 5.575 # qt
}
if (TERM eq "pngcairo") {
set term pngcairo size 800,600
set output "tbDashTest.png"
FactorX = 0.249 # pngcairo
FactorY = 0.251 # pngcairo
}
set multiplot
set ticscale 0,0
Units = 24 # pattern (5,5,4,5,5,0) are 24 units
# set interval and repetition parameters
IntervalsY = 10
RepetitionsY = 1
IntervalsX = 4
RepetitionsX = 3
# initial plot to get graph size
plot x**2
gX = real(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)/IntervalsY/Units/FactorY/RepetitionsY
gY = real(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)/IntervalsX/Units/FactorX/RepetitionsX
# first plot with x-grid lines
set grid xtics lt 1 lc rgb "black" dt (gX*5,gX*5,gX*4,gX*5,gX*5,0)
replot
unset grid
# second plot with y-grid lines
set grid ytics lt 1 lc rgb "black" dt (gY*5,gY*5,gY*4,gY*5,gY*5,0)
replot
unset multiplot
set output
### end of code
Result:
Not really. The closest I can think of is
set grid x y mx my
set grid lt -1 lc "black" lw 1 , lt -1 lc bgnd lw 16
set ticscale 1.0, 0.01
set mxtics 4
plot x**2 lw 2
But that leaves the vertical grid lines solid.

How to add symbols representing point types in y labels

I want to add the symbols representing point types to y and y2 labels.
Here is the test code:
set key center top;
set ylabel "x";
set y2label "x^2";
plot x w lp pt 5 pi 5, x**2 w lp pt 7 pi 5 axes x1y2;
It gives:
I want the following:
Is there anyway to achieve this in Gnuplot?
I am using Gnuplot 4.6.5.
Thanks.
One option would be to use set label ... point pt 7 lt 2 to place a dot somewhere. But that needs a lot of tweaking to get the correct position. And that position would need to be adapted manually depending on the font, font size, canvas size etc.
If only the point shape is important, you can use the respective glyph from the unicode block: geometric shapes. This is also from where I copied the symbols to the script. You must of course also use a font which includes the respective glyphs (e.g. Arial Unicode or DejaVu) and a proper terminal (e.g. pdfcairo, pngcairo, wxt are all fine):
set terminal pngcairo enhanced font "DejaVu" size 600,300
set output 'square-circle.png'
set key center top
set encoding utf8
set ylabel "x {/*0.8 ■}"
set y2label "x^2 {/*0.8 ●}"
plot x w lp pt 5 pi 5, x**2 w lp pt 7 pi 5 axes x1y2;
Result with 4.6.5 is:

gnuplot text color palette

I am trying to set textcolor property of a label in gnuplot to transition through a palette of colours.
To be more precise, I want each letter of the label, say "Number of Connections", to be a different color but following the color palette I specify.
I tried using the following method, but it failed, using only the color in the middle of the range for the string.
set palette model RGB defined ( \
0 '#F46D43',\
1 '#FDAE61',\
2 '#FEE08B',\
3 '#E6F598',\
4 '#ABDDA4',\
5 '#66C2A5' )
set y2label "Number of Connections" textcolor palette
Unfortunately, gnuplot can only color the entire string "Number of Connections". You can influence the color using the additional frac option.
However, here's a way to achieve what you were looking for. It involves some manual settings, though, as I'll explain below:
# define the location of your plot:
bm = 0.15
lm = 0.12
rm = 0.75
tm = 0.90
# letter spacing - play with this as needed:
STRDIST = 0.03
# set up the plot window:
set lmargin at screen lm
set rmargin at screen rm
set bmargin at screen bm
set tmargin at screen tm
# place the colorbar in a defined location:
set colorbox vertical user origin rm+0.1,0.15 size .05,tm-bm
# define your palette:
set palette model RGB defined ( \
0 '#F46D43',\
1 '#FDAE61',\
2 '#FEE08B',\
3 '#E6F598',\
4 '#ABDDA4',\
5 '#66C2A5' )
# your label
LABEL = "Number of Connections"
# the 'length' of LABEL, unfortunately counted manually:
LEN_LABEL = 21.0 # IMPORTANT, declare as float
# use a loop to individually place each char of the string on the plot:
do for [i=1:LEN_LABEL]{\
set label i LABEL[i:i] at screen 0.8,bm+((i-1.)*STRDIST) \
rotate by 90 textcolor palette frac i/LEN_LABEL\
}
# dummy function plot (so that there's something to see):
plot '+' using ($1):(sin($1)):(0.5*(1.0+sin($1))) w l lw 3 lc pal not
What is going on:
Define the location of your plot and of the colorbar: That way you will know exactly where they are and can place a "pseudo"-label accurately.
The variable STRDIST is used to space the individual letters. This is clumsy, but you get the gist. Play with it to achieve good results.
Unfortunately, it seems that gnuplot cannot compute the length of a string, so I hard-wired it, LEN_LABEL.
Use a do for-loop to place each letter of the label string on the plot, assigning a color from the color palette using the additional frac option. frac 0.0 is the lowest and frac 1.0 the "highest" color on the color palette. Here, we exploit the loop-counter to give evenly spaced colors from the palette. Note: This is why it is important to declare LEN_LABEL as a float, not integer or everything but the last iteration will result in frac 0.
The plot '+' ... command is borrowed from this site.
The plot you get when you copy/paste the above example looks like this:
Play with the starting point of the "label" as well as the STRDIST to generate/place a label of your liking.

Resources