similar to this question here I want to draw process tree where a PID is given, I should be able to draw that process and its children as a tree. However, I want to preserve parent children relationship between nodes/edges. What I mean is, any two children should not have edge between. Coordinates actually do not matter. Also, I am open for other drawing tool options. I tried the accepted answer of mentioned question but it links all nodes.
Any kind of suggestion/help would make my day.
Note: I am using Ubuntu
You don't give too many details what you have and what you exactly want. So I assume something. Certainly, room for improvements. To learn more about plotting styles, in gnuplot console check help points
, help vectors
, help labels
.
Script:
### drawing a simple tree
reset session
$Children <<EOD
23
34
45
56
67
78
EOD
$Parent <<EOD
123
EOD
unset border
unset tics
set offsets 0.2,0.2,0.2,0.2
set key noautotitle
Size = 8
plot $Children u (Last=$0):(1):1 w labels, \
'' u 0:(1):(Last/2-$0):(1) w vec nohead lc rgb "black", \
'' u 0:(1):(Size) w p pt 7 ps var lc rgb "yellow", \
'' u 0:(1):1 w labels, \
$Parent u (Last/2):(2):(Size) w p pt 7 ps var lc rgb "light-grey", \
'' u (Last/2):(2):1 w labels center
### end of script
Result:
Addition:
Actually, you can do a bit more complex tree diagrams with gnuplot. Fortunately, gnuplot allows for recursive functions.
The input consists out of 5 columns without header. Each ID has only one parent, except one which is the top node. An ID can have several children.
Prerequisites:
NaN
for the top node.Improvements are welcome.
Script: (actually some "nonsense" tree)
### tree diagram with gnuplot
reset session
#ID Parent Name Shape Color
$Data <<EOD
1 NaN Ant 4 0xffcccc
2 1 Ape 14 0xccffcc
3 1 Ass 6 0xcccccc
4 2 Bat 6 0xffffff
5 2 Bee 6 0xcccccc
6 2 Cat 6 0xffffcc
7 3 Cod 6 0xcccccc
8 3 Cow 6 0xcccccc
9 3 Dog 12 0xccffcc
10 7 Eel 6 0xffffff
11 7 Elk 6 0xffcccc
12 7 Emu 6 0xccccff
13 9 Fly 6 0xcccccc
14 9 Fox 6 0xcccccc
15 4 Gnu 4 0xffcccc
16 1 Hen 6 0xffccff
17 16 Hog 6 0xcccccc
18 12 Jay 4 0xffcccc
19 12 Owl 6 0xccffff
20 15 Pig 6 0xffffcc
21 15 Pug 6 0xcccccc
22 12 Ram 4 0xcccccc
23 14 Rat 4 0xffffff
24 12 Sow 6 0xffffff
25 7 Yak 6 0xcccccc
EOD
# put datablock into strings
IDs = Parents = Names = Shapes = Colors = ''
addToList(list, col) = sprintf("%s %s", list, strcol(col))
stats $Data u (IDs = addToList(IDs,1), \
Parents = addToList(Parents,2), \
Names = addToList(Names,3), \
Shapes = addToList(Shapes,4), \
Colors = addToList(Colors,5)) nooutput
# Top node has no parent ID 'NaN'
Start(n) = int(sum [i=1:words(Parents)] (word(Parents,i) eq 'NaN' ? int(word(IDs,i)) : 0))
# get list index by ID
ItemIdx(s,n) = n == n ? (tmp=NaN, sum [i=1:words(s)] ((word(s,i)) == n ? (tmp=i,0) : 0), tmp) : NaN
# get parent of ID n
Parent(n) = word(Parents,ItemIdx(IDs,n))
# get level of ID n, recursive function
Level(n) = n == n ? Parent(n)>0 ? Level(Parent(n))-1 : 0 : NaN
# get number of children of ID n
ChildCount(n) = int(sum [i=1:words(Parents)] (word(Parents,i)==n))
# Create child list of ID n
ChildList(n) = (Ch = ' ', sum [i=1:words(IDs)] (word(Parents,i)==n ? (Ch = Ch.word(IDs,i).' ',1) : (Ch,0) ), Ch )
# m-th child of ID n
Child(n,m) = word(ChildList(n),m)
# List of leaves, recursive function
LeafList(n) = (LL='', ChildCount(n)==0 ? LL=LL.n.' ' : sum [i=1:ChildCount(n)] (LL=LL.LeafList(Child(n,i)), 0),LL)
# create list of all leaves
LeafAll = LeafList(Start(0))
# get x-position of ID n, recursive function
XPos(n) = ChildCount(n) == 0 ? ItemIdx(LeafAll,n) : (sum [i=1:ChildCount(n)] (XPos(Child(n,i))))/(ChildCount(n))
# create the tree datablock for plotting
set print $Tree
do for [j=1:words(IDs)] {
n = int(word(IDs,j))
print sprintf("% 3d % 7.2f % 4d % 5s % 4s % 10s", \
n, XPos(n), Level(n), word(Names,j), word(Shapes,j), word(Colors,j))
}
set print
print $Tree
# get x and y distance from ID n to its parent
dx(n) = XPos(Parent(int(n))) - XPos(int(n))
dy(n) = Level(Parent(int(n))) - Level(int(n))
unset border
unset tics
set offsets 0.25, 0.25, 0.25, 0.25
set key noautotitle
plot $Tree u 2:3:(dx($1)):(dy($1)) w vec nohead ls -1,\
'' u 2:3:($5+1):6 w p pt var ps 6 lc rgb var, \
'' u 2:3:5 w p pt var ps 6 lw 1.5 lc rgb "black", \
'' u 2:3:4 w labels offset 0,0.1 center
### end of script
Result: