Compose data points with connecting lines, but leaving spaces
I like the following linespoints
plotting style:
http://www.gnuplotting.org/join-data-points-with-non-continuous-lines/
However, I ran into a problem when I draw multiple lines with this style:
As you can see the second series of dots is empty, also the first series (lines and dots), which is not what I want.
The feature of gnuplot that makes this possible is pointinterval
and pointintervalbox
.
Gnuplot documentation:
A negative value
pointinterval
, for example. -N means that dot symbols are drawn only for every Nth point and that the box (actually a circle) behind each dot symbol is shaded by filling the background color . The commandset pointintervalbox
controls the radius of this filled area. This is a multiplier for the default radius, which is the size of the point.
http://www.bersch.net/gnuplot-doc/set-show.html#set-pointintervalbox
As the doc says fill in the background color, I was hoping to use the background transparent , the problem could be solved but it seems that the color is white.
Gnuplot version
gnuplot> show version long
G N U P L O T
Version 5.0 patchlevel 0 last modified 2015-01-01
Copyright (C) 1986-1993, 1998, 2004, 2007-2015
Thomas Williams, Colin Kelley and many others
gnuplot home: http://www.gnuplot.info
faq, bugs, etc: type "help FAQ"
immediate help: type "help" (plot window: hit 'h')
Compile options:
-READLINE +LIBREADLINE +HISTORY
-BACKWARDS_COMPATIBILITY +BINARY_DATA
+GD_PNG +GD_JPEG +GD_TTF +GD_GIF +ANIMATION
-USE_CWDRC +HIDDEN3D_QUADTREE
+DATASTRINGS +HISTOGRAMS +OBJECTS +STRINGVARS +MACROS +THIN_SPLINES +IMAGE +USER_LINETYPES +STATS +EXTERNAL_FUNCTIONS
Minimum Working Example (MWE):
gnuplot-space-line-mark-style.gp
reset
set terminal pngcairo transparent size 350,262 enhanced font 'Verdana,10'
show version
set output 'non-continuous_lines.png'
set border linewidth 1.5
set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 pi -1 ps 1.5
set style line 2 lc rgb '#0020ad' lt 1 lw 2 pt 7 pi -1 ps 1.5
set pointintervalbox 3
unset key
set ytics 1
set tics scale 0.75
set xrange [0:5]
set yrange [0:4]
plot 'plotting_data1.dat' with linespoints ls 1,\
'plotting_data2.dat' with linespoints ls 2
plotting_data1.dat
# X Y
1 2
2 3
3 2
4 1
plotting_data2.dat
# X Y
1.2 2.4
2 3.5
3 2.5
4 1.2
UPDATE
A working pgfplots
solution is given at tex.stackoverflow.com
source to share
You can do a lot with Gnuplot. It's just a matter of how difficult you make it. You can implement the break with a two-step build. The first one: only the with points
second: with vectors
which are the lines between the points, cut by doing some geometric calculations. The parameter L1
defines the gap and should be adjusted taking into account the data scale and graph. Tested with gnuplot 5.0 and 5.2.
Revised version:
Here is a version that creates gaps regardless of terminal size and chart scale. It just takes a little more scaling. However, since it requires the size of the terminal and the chart, which are stored in GPVAL_...
-variables, which you only get after plotting, this unfortunately requires reprinting. I'm not sure if this works for all terminals. I just checked on wxt terminal.
Empirical conclusions (for wxt terminal on Win7):
pointsize 100
(ps) corresponds to 600
pixels (pix), hence: Rpxps=6
(ratio of pixels to point size)
term size 400,400
(px) matches 8000,8000
terminal units (tu), hence: Rtupx=20
(ratio of terminal units to pixels)
Change: The rate Rtupx
is obviously different for different terminals: wxt: 20
, qt: 10
, pngcairo: 1
, you can use a variable GPVAL_TERM
to test the terminal.
Rtupx = 1. # for pngcairo terminal 1 tu/px
if (GPVAL_TERM eq "wxt") { Rtupx = 20. } # 20 tu/px, 20 terminal units per pixel
if (GPVAL_TERM eq "qt") { Rtupx = 10. } # 10 tu/px, 10 terminal units per pixel
The ratios of axial units (au) to final units (tu) are different for x and y and are:
Rxautu = (GPVAL_X_MAX-GPVAL_X_MIN)/(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)
Ryautu = (GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)
The variable GapSize
is specified in points of the dimension. In fact, the actual size of the gap depends on the size of the dots (as well as the line width). For simplicity, here the gap size refers to the distance from the center of the point to the beginning of the line. Thus, GapSize=1.5
if you have it pointsize 1.5
will break in 0.75
on each side. L3(n)
from an earlier version is now replaced with L3px(n)
in pixel dimensions, and L1
from an earlier version is no longer required.
Code:
### "linespoints" with gaps between lines and points
reset session
$Data1 <<EOD
# X Y
0 3
1 2
1.5 1
3 2
4 1
EOD
$Data2 <<EOD
0 0
1 1
2 1
2 2
3 1
3.98 0.98
EOD
GapSize = 1.5
Rtupx = 20. # 20 tu/px, 20 terminal units per pixel
Rpxps = 6. # 6 px/ps, 6 pixels per pointsize
# Ratio: axis units per terminal units
Rxautu(n) = (GPVAL_X_MAX-GPVAL_X_MIN)/(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)
Ryautu(n) = (GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)
dXpx(n) = (x3-x0)/Rxautu(n)/Rtupx
dYpx(n) = (y3-y0)/Ryautu(n)/Rtupx
L3px(n) = sqrt(dXpx(n)**2 + dYpx(n)**2)
x1px(n) = dXpx(n)*GapSize*Rpxps/L3px(n)
y1px(n) = dYpx(n)*GapSize*Rpxps/L3px(n)
x2px(n) = dXpx(n)*(L3px(n)-GapSize*Rpxps)/L3px(n)
y2px(n) = dYpx(n)*(L3px(n)-GapSize*Rpxps)/L3px(n)
x1(n) = x1px(n)*Rtupx*Rxautu(n) + x0
y1(n) = y1px(n)*Rtupx*Ryautu(n) + y0
x2(n) = x2px(n)*Rtupx*Rxautu(n) + x0
y2(n) = y2px(n)*Rtupx*Ryautu(n) + y0
set style line 1 pt 7 ps 1.5 lc rgb "black"
set style line 2 lw 2 lc rgb "black
set style line 3 pt 7 ps 1.5 lc rgb "red"
set style line 4 lw 2 lc rgb "red"
plot \
$Data1 u (x3=NaN, y3=NaN,$1):2 w p ls 1 notitle, \
$Data1 u (y0=y3,y3=$2,x0=x3,x3=$1,x1(0)):(y1(0)): \
(x2(0)-x1(0)):(y2(0)-y1(0)) w vectors ls 2 nohead notitle, \
$Data2 u (x3=NaN, y3=NaN,$1):2 w p ls 3 notitle, \
$Data2 u (y0=y3,y3=$2,x0=x3,x3=$1,x1(0)):(y1(0)): \
(x2(0)-x1(0)):(y2(0)-y1(0)) w vectors ls 4 nohead notitle
replot
### end of code
Result: (two different terminal sizes)
Explanations:
-
Q: Why is there an argument
(n)
forL3(n)
,x1(n)
,y1(n)
,x2(n)
,y2(n)
?n
always equal to0
whenL3(n)
, ... are calculated and not used on the right side.
Answer: To make them non-constant expressions. Alternatively you can addx0,x3,y0,y3
as variables, for exampleL3(x0, y0, x3, y3)
; However, the compactness will be lost. -
Question: What does
using
in meanplot $Data1 using (x3=NaN,y3=NaN,$1):2
?
Answer: This(,)
is called sequential scoring, which is described under Expressions> Operator> Binary in the gnuplot documentation (v4.4 or newer only). Sequential evaluation only happens in parentheses and is guaranteed to be done in left-to-right order. The value of the rightmost subexpression is returned. This is done here to initialize(x3,y3)
for subsequent plotting of line segments as vectors. It doesn't matter for plotting points. -
Question: How does this draw
N-1
segments / vectors forN
points?
Answer: Settingx3=NaN, y3=NaN
when plotting points ensures that for the first data point, the starting data point(x0,y0)
is set to(NaN,NaN)
which will result in an estimatex1(0)
andy1(0)
also returnsNaN
.
Gnuplot generally skips points cNaN
, i.e. the vector is not drawn for the first data point. The code draws a line between the first and second point when the iteration reaches the second point. -
Question: How does the second
plot '' u...
iterate over all points?
A:gnuplot> h special-filenames
I explain it:
There are a few filenames that have a special meaning:''
,'-'
,'+'
and'++'
.
An empty filename''
tells gnuplot to reuse the previous input file in the same plot command. So, to plot two columns from one input file:plot 'filename' using 1:2, '' using 1:3
-
Question: are parentheses needed
(y1(0))
?
Answer:gnuplot> h using
Explains it:
Each can be a simple column number that selects a value from one field in an input file, a string that matches the column label in the first row of the dataset, an expression enclosed in parentheses, or a special function not enclosed in parentheses, such as howxticlabels(2)
.
source to share