Gnuplot - plotting label with different lines in hypertext - plot

Having the following text file
0 0 net0 aaaa bbbb cccc
1 1 net1 zzz
2 2 net2 xxx
3 3 net3 yyy
4 5 net4 ttt 0 0
5 5 net5
I need to plot all points described by the first two columns as x,y coordinates and anchoring the informations reported in the following columns (say 3:6) at each point.These info have to be plot separated by newlines, e.g. the point in (0,0) should report (when mouse over it)
net0
aaaa
bbbb
cccc
The script I'm using is the following but it works only with three columns
set terminal canvas enhanced mousing
set termoption enhanced
set label at 0,0 "Origin"
set title 'mouse over points'
plot 'test.txt' using 1:2:3 with labels hypertext point pt 7 ps var lc rgb "black"
It seems that the datafile modifier using works only with three entries.
Any help?

It is unfortunate that your text is not surrounded by "". Nevertheless, you can handle your issue with gnuplot without any external tool.
You didn't specify whether your data columns are separated by TAB or by space.
In the following, I assume that they are separated by single space (code needs to be adapted accordingly if not).
Procedure:
Read the data as full line by setting set datafile separator "\n"
extract the numbers with word()
take the rest of the line as your label text
replace spaces by '\n'
Code:
### Hypertext with columns
reset session
$Data <<EOD
0 0 net0 aaaa bbbb cccc
1 1 net1 zzz
2 2 net2 xxx
3 3 net3 yyy
4 5 net4 ttt 0 0
5 5 net5
EOD
# replace function
# replaces string s1 by string s2 in string s
Replace(s,s1,s2) = (RP_s="", RP_n=1, (sum[RP_i=1:strlen(s)] \
((s[RP_n:RP_n+strlen(s1)-1] eq s1 ? (RP_s=RP_s.s2, RP_n=RP_n+strlen(s1)) : \
(RP_s=RP_s.s[RP_n:RP_n], RP_n=RP_n+1)), 0)), RP_s)
set datafile separator "\n"
GetNumber(n) = real(word(strcol(1),n))
GetText(s) = (s[strstrt(s," ")+1:])[strstrt(s[strstrt(s," ")+1:]," ")+1:]
TextToColumn(s) = Replace(GetText(s),' ','\n')
plot $Data u (GetNumber(1)):(GetNumber(2)):(TextToColumn(strcol(1))) w labels hypertext \
point pt 7 ps 3 lc rgb "red" notitle
### end of code
Result:

Related

Adding an extra line to a text file after every N lines

Hi I have a Unix command that produces a list of ip addresses along with other columns information . i want to add something to the command so that it displays it as a set of 3 lines then a space or ---- and then the next 3 lines and so on.
how can I achieve this ?
for example:
1.2.3.4 xy
1.3.5.7 ab
1.25.7.9 cd
-------------
1.25.7.8 kl
1.3.4.5 mn
1.25.7.8 op
-------------
1.24.5.6 la
1.3.4.5 ka
1.25.7.8 xz
You can use awk to print an extra line after every 40 lines:
awk '{ print $0; if(++i % 40 == 0) printf("-------------\n") }' file
Change % 40 to % 3 to print that extra line after every 3 lines.
$ seq 9 | awk 'NR>1 && (NR%3)==1{print "---"} 1'
1
2
3
---
4
5
6
---
7
8
9

How to plot a tree/graph/web with weighted edges in Gnuplot?

i am plotting a tree in gnuplot as discussed here (How to plot tree/graph/web data on gnuplot?). However, i would like to include the edges weight of the tree, i.e. for each edge i have a number (e.g. 10, 20, 30, 40) that represents the edge weight. The figure below shows in red the edges weight that i want to plot in gnuplot (i added this using power point).
Can anyone tell me how to plot edges with weight in gnuplot?
I would propose a slight variation on the answer which you mention in your question. Let's assume that the coordinates of the vertices are stored in a file pnts.dat as follows:
0 5 10
1 20 20
2 15 15
3 30 30
4 40 10
Here, the first column records the corresponding label, while second and third columns contain the x- and y-coordinate, respectively.
The edges could be defined in a separate file edges.dat as:
0 1 30 0 1
1 2 40 0 -2
1 4 20 0 1
1 3 10 0 1
Here, the first two column contain the point indices (they refer to the first column of pnts.dat). The third column records the weight of a particular edge. Finally, the last two columns contain the x,y displacement of the generated associated label.
With this, the Gnuplot script could look like:
set xr [0:50]
set yr [0:50]
set size square
flePnts = 'pnts.dat'
fleEdges = 'edges.dat'
loadEdges = sprintf('< gawk '' \
FNR==NR{x[$1]=$2;y[$1]=$3;next;} \
{printf "%%f\t%%f\n%%f\t%%f\n\n", x[$1], y[$1], x[$2], y[$2];} \
'' %s %s', flePnts, fleEdges);
loadWeights = sprintf('< gawk '' \
FNR==NR{x[$1]=$2;y[$1]=$3;next;} \
{printf "%%f\t%%f\t%%s\n", (x[$1]+x[$2])/2 + $4, (y[$1]+y[$2])/2 + $5, $3} \
'' %s %s', flePnts, fleEdges);
plot \
loadEdges using 1:2 with lines lc rgb "black" lw 2 notitle, \
flePnts using 2:3:(0.6) with circles fill solid lc rgb "black" notitle, \
flePnts using 2:3:1 with labels tc rgb "white" font "Arial Bold" notitle, \
loadWeights using 1:2:3 with labels tc rgb "red" center font "Arial Bold" notitle
the loadEdges command invokes gawk in order to generate for all edges the corresponding pairs of x/y coordinates (delimited by a blank line)
loadWeights calculates for each edge the middle point and places a label at these coordinates (taking into account the required offset)
Finally, one obtains:
Addicionally, if you want to add arrows to the edges, you have to do these steps:
Add the arrow style:
set style arrow 1 head filled size screen 0.025,10,40 lc rgb "black" lw 2
Change the command with lines for with vectors
loadEdges using 1:2:3:4 with vectors arrowstyle 1 notitle, \
The following image show you the final result:
And this is the final code:
set xr [0:50]
set yr [0:50]
set size square
set style arrow 1 head filled size screen 0.025,10,40 lc rgb "black" lw 2
flePnts = 'pnts.dat'
fleEdges = 'edges.dat'
loadEdges = sprintf('< gawk '' \
FNR==NR{x[$1]=$2;y[$1]=$3;next;} \
{printf "%%f\t%%f\t%%f\t%%f\n\n", x[$1], y[$1], (x[$2]-x[$1]), (y[$2]-y[$1]);} \
'' %s %s', flePnts, fleEdges);
loadWeights = sprintf('< gawk '' \
FNR==NR{x[$1]=$2;y[$1]=$3;next;} \
{printf "%%f\t%%f\t%%s\n", (x[$1]+x[$2])/2 + $4, (y[$1]+y[$2])/2 + $5, $3} \
'' %s %s', flePnts, fleEdges);
plot \
loadEdges using 1:2:3:4 with vectors arrowstyle 1 notitle, \
flePnts using 2:3:(0.6) with circles fill solid lc rgb "black" notitle, \
flePnts using 2:3:1 with labels tc rgb "white" font "Arial Bold" notitle, \
loadWeights using 1:2:3 with labels tc rgb "red" center font "Arial Bold" notitle
Here is a suggestion which resembles #ewcz's solution, i.e. using a list of IDs with x,y coordinates and a list of connections using two IDs.
However, with the following differences:
all data in one file (in two different blocks addressed with index)
a gnuplot-only solution without awk or gawk and hence platform-independent. A lookup list is created with gnuplot, similar to this answer.
individual label offsets with rotation angle dA and relative length dR between the points (dR=0: at center of connector, dR=-1: at starting point,dR=1: at end point). Because of this, is recommended to use set size ratio -1 such that e.g. a rotation by 45 degrees is visually 45 degrees in the graph.
Data: SO42447683.dat
# ID x y
0 5 10
1 20 20
2 15 15
3 30 30
4 40 10
# ID1 ID2 weight dA dR
0 1 30 7 0
1 2 40 20 0
1 4 20 0 0
1 3 10 0 0
Script: (works for gnuplot>=5.0.0, without option textbox it works with >=4.6.0)
### plot tree with different labels
reset
FILE = "SO42447683.dat"
set size ratio -1
set key noautotitle
set offsets 0.5,0.5,0.5,0.5
set angle degrees
set style textbox opaque noborder
IdIdxs = XYs = ' '
stats FILE u (IdIdxs=IdIdxs.sprintf("%s:%d ",strcol(1),$0), \
XYs=XYs.sprintf("%g %g ",$2,$3)) index 0 nooutput
Px(i) = real(word(XYs,2*i+1))
Py(i) = real(word(XYs,2*i+2))
getIdx(col) = (c0=strstrt(IdIdxs,sprintf(" %s:",strcol(col))), \
c1=strstrt(IdIdxs[c0+1:],' ')+c0, \
s0=IdIdxs[c0:c1], c2=strstrt(s0,':'), int(s0[c2+1:]))
getLxy(colA,colR) = (idx0=getIdx(1), x0=Px(idx0),y0=Py(idx0), \
idx1=getIdx(2), x1=Px(idx1),y1=Py(idx1), \
rm = sqrt((x1-x0)**2+(y1-y0)**2)*(column(colR)+1)*0.5, \
a = atan2(y1-y0,x1-x0)+column(colA), \
Ly = y0+rm*sin(a), Lx=x0+rm*cos(a))
plot FILE index 1 u (idx0=getIdx(1),x0=Px(idx0)):(y0=Py(idx0)): \
(idx1=getIdx(2),Px(idx1)-x0):(Py(idx1)-y0) w vec lw 2 lc rgb "black" nohead, \
'' index 0 u 2:3 w p pt 7 ps 4 lc rgb "white",\
'' index 0 u 2:3 w p pt 6 ps 4 lc rgb "black",\
'' index 0 u 2:3:1 w labels, \
'' index 1 u (getLxy(4,5)):(Ly):3 w labels tc rgb "red" boxed
### end of script
Result:

gnuplot: with x and y-axis label (rowstacked) with row and column names

I haven't answer the question after I google it.
I have data.txt like this:
a b c
sys1 3 2 0
sys2 4 4 4
sys3 5 2 4
sys4 6 4 1
I created graphs using rowstacked style with pattern, currently I select the patterns manually. I have to plotting my data.txt with sys1-sys4 and a-c. This matrix always have the same size, but I should do sorting and re generate with different order sequence.
this is my gnuplot script:
set term pos eps font 20
set style data histogram
set style histogram rowstacked
set key invert reverse right outside # above outside or left outside
set boxwidth 0.75
set ylabel "Count"
set xlabel "System"
set xtics nomirror rotate by -270
set output 'eps/a1-count.eps'
plot 'a1-count' \
using($2):xtic(1) title "data 1" lt -1 fs pattern 3, \
'' using($3) title "data 2" lt -1 fs pattern 4, \
'' using($3) title "data 3" lt -1 fs pattern 6
and this is the output:
I also found some solution here but it is for heat map. Anyone can help me?
Thanks a lot!
you can sort directly the data within gnuplot : (-nk[column]), with linux 'sort' command:
plot '<sort -nk1 data.txt' \
u 2:xtic(1) title "data 1" lt -1 fs pattern 3, \
'' u 3 title "data 2" lt -1 fs pattern 4, \
'' u 3 title "data 3" lt -1 fs pattern 6
The '' empty string file call, will keep the sorted datafile.
the title of your question is not correct, but thanks to you, i learnd the :xtic(column) feature and the correct way of doing :
set xtics nomirror rotate by -270
Regards,

gnuplot: mark/highlight area (part of linegraph)

my data is quite simple, just a timestamp and a number like this:
2013-01-23 08:27:55 2801
2013-01-23 08:33:13 2801
2013-01-23 08:38:31 2660
2013-01-23 08:43:49 2785
2013-01-23 08:49:07 2785
I get the data from a another system. Space between date and time, and tabulator between "date time" and the number.
The whole time window is a few hours .. a couple of days. This overall time window contains one or more interesting parts (typically few..several hours), and I would like to mark or highlight these interesting parts somehow to make it easier and faster to analyse the graphs.
Th einteresting time window would need to be specified manually, e.g. from 2014-01-23 10:00:00 to 2013-01-24 12:00:00 for 2 hour window.
Drawing a rectancle to the background of the linegraph is one possibility, and changing the line color (or something similar) is another.
How can I do that from manually/separately defined time stamps? The best I was able to find was splitting the data with empty lines, and use something like this (from http://www.gnuplotting.org/introduction/plotting-data/):
set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 ps 1.5 # --- blue
set style line 2 lc rgb '#dd181f' lt 1 lw 2 pt 5 ps 1.5 # --- red
plot 'plotting-data3.dat' index 0 with linespoints ls 1, '' index 1 with linespoints ls 2
But splitting the data is a bit arduous (?); I'm looking for elegant gnuplot means to achive the goal. Robust splitting could be possible as well, if thats really the best alternative.
Below is the plotting function, works well but I'd like to mark/highlight selected parts of the graph.
-Paavo
function my_gnuplot {
if [ $# -ne 3 -o -z "$1" -o -z "$2" -o -z "$3" ]
then
echo $0 $FUNCNAME Invalid parameters, exiting
exit 3
fi
sid="$1" ; shift
stime="$1" ; shift
etime="$1" ; shift
if [ $sid -gt 0 -a $sid -lt 10 ]
then
title=0$sid
else
title=$sid
fi
gnuplot <<- EOF
reset
set terminal png size 1800,900 enhanced font myfont.ttf 10
set xdata time
set timefmt "%Y-%m-%d %H:%M:%S"
set format x "%Y-%m-%d %H:%M"
set title "SID=$title from $stime to $etime"
set grid
set xrange [ "$stime" : "$etime" ]
set yrange [ -2000 : 6000 ]
set style data linespoints
plot "sid_data_$sid.txt" using 1:9 notitle
EOF
}
You can use rectangles to fill the space pretty easily:
set xdata time
set timefmt '%Y-%m-%d %H:%M:%S'
set object 1 rectangle from "2013-01-23 08:33:13",graph 0 to "2013-01-23 08:43:49",graph 1 fs solid fc rgb "red" behind
plot 'test.dat' u 1:3 w lines ls -1

Gnuplot: Multiple Stacked Histograms, each group using the same key

I am trying to create a plot with multiple stacked histograms like example 8 here. But for my data, each group has the same four categories.
How do I change the colors and the key so that colors go Red, Green, Blue, Pink for every stacked column? And so the key only has one copy each of the 4 things I am plotting?
Here is the line I'm using to plot:
plot newhistogram "1", 'addresses.dat' using 2:xtic(1) t 2, '' u 3 t 3, \
'' u 4 t 4, '' u 5 t 5, newhistogram "2", '' u 6 t 6, '' u 7 t 7, '' u 8 t 8,\
'' u 9 t 9
My data is in the same format as the example I linked to above:
Address PAL_Code BASH App Kernel PAL_Code BASH App Kernel
FFT 1 1 2 2 1 1 3 4
RADIX 1 2 3 4 1 2 4 5
LU 1 3 4 5 1 3 5 6
Thank you so much if you can help!
use the ltspecifier behind newhistogram in order to specify the first color gnuplot should use. I wrote a little script that might does what you want;)
set style data histogram
set style histogram rowstack gap 1
set style fill solid border -1
set boxwidth 0.9
set key autotitle columnheader
set key outside below center horizontal
plot newhistogram "1" lt 1, 'addresses.dat' u 2:xtic(1), '' u 3, '' u 4, '' u 5,\
newhistogram "2" lt 1, 'addresses.dat' u 6:xtic(1) notitle, '' u 7 notitle, \
'' u 8 notitle, '' u 9 notitle
Hope that helps
Cherio
Woltan

Resources