ubuntu - 使用 gnuplot 绘制进程树
问题描述
与这里的这个问题类似, 我想在给定 PID 的地方绘制进程树,我应该能够将该进程及其子进程绘制为树。但是,我想保留节点/边之间的父子关系。我的意思是,任何两个孩子之间都不应该有优势。坐标实际上并不重要。此外,我对其他绘图工具选项持开放态度。我尝试了上述问题的公认答案,但它链接了所有节点。
任何形式的建议/帮助都会让我开心。
注意:我使用的是 Ubuntu
解决方案
你没有给出太多细节你有什么和你到底想要什么。所以我假设一些事情。当然,还有改进的余地。要了解有关绘图样式的更多信息,请在 gnuplot 控制台中检查help points
、help vectors
、help labels
。
代码:
### drawing a simple tree
reset session
$Children <<EOD
23
34
45
56
67
78
EOD
$Parent <<EOD
123
EOD
unset border
unset tics
Size = 8
set offsets 0.2,0.2,0.2,0.2
plot $Children u (Last=$0):(1):1 w labels not, \
'' u 0:(1):(Last/2-$0):(1) w vectors nohead lc rgb "black" notitle, \
'' u 0:(1):(Size) w p pt 7 ps var lc rgb "yellow" not, \
'' u 0:(1):1 w labels not, \
$Parent u (Last/2):(2):(Size) w p pt 7 ps var lc rgb "light-grey" not, \
'' u (Last/2):(2):1 w labels center not
### end of code
结果:
添加:
实际上,您可以使用 gnuplot 制作更复杂的树形图。幸运的是,gnuplot 允许递归函数。
输入由 3 列组成,没有标题。每个 ID 只有一个父节点,除了一个是顶部节点。一个 ID 可以有多个孩子。
先决条件:
- 第 1 列包含唯一的整数 ID 号
NaN
第 2 列包含第 1 列中子 ID 或顶部节点的父 ID 。- 第 3 列节点标签名称
欢迎改进。
代码:(实际上是一些“废话”树)
### tree diagram with gnuplot
reset session
#ID Parent Name
$Data <<EOD
1 NaN Ant
2 1 Ape
3 1 Ass
4 2 Bat
5 2 Bee
6 2 Cat
7 3 Cod
8 3 Cow
9 3 Dog
10 7 Eel
11 7 Elk
12 7 Emu
13 9 Fly
14 9 Fox
15 4 Gnu
16 1 Hen
17 16 Hog
18 12 Jay
19 12 Owl
20 15 Pig
21 15 Pug
22 12 Ram
23 14 Rat
24 12 Sow
25 7 Yak
EOD
# put datablock into strings
IDs = Parents = Names = ''
set table $Dummy
plot $Data u (IDs = IDs.strcol(1).' '): \
(Parents = Parents.strcol(2).' '): \
(Names = Names.strcol(3).' ') w table
unset table
# 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", n, XPos(n), Level(n), word(Names,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
plot $Tree u 2:3:(dx($1)):(dy($1)) w vec nohead ls -1 not,\
'' u 2:3 w p pt 7 ps 6 lc rgb 0xccffcc not, \
'' u 2:3 w p pt 6 ps 6 lw 1.5 lc rgb "black" not, \
'' u 2:3:4 w labels offset 0,0.1 center not
### end of code
结果:
推荐阅读
- python - 如何求和找到几个日期时间的平均值
- kql - Kusto 查询如何将表中的每一行作为参数进行迭代以在另一个表中查询?
- java - 如何修复 Java Swing JFrame 的大小错误
- c++ - 嵌套类的模板模板参数的可变类型模板参数和非类型模板参数如何相互约束?
- php - 如何在 PHP 中加二?
- prolog - Prolog递归迭代列表失败
- python - 在 Ruby / Python 中实现 Umbraco/ASP.NET 密码验证脚本
- r - R - 在新数据框中:如果单元格与同一行的另一列匹配,则
- python - python 新手,在 while 和 ifs 上有问题
- android - 将整个布局转换为图像/位图