用gnuplot绘制过程树(更改节点颜色和形状)

时间:2020-07-06 21:30:21

标签: gnuplot

我想出了this精彩的答复,它回答了一段时间前提出的有关如何绘制树的问题。我一直在尝试根据数据中的附加列来更改某些节点的颜色和形状。对于上下文,构建层次树图的另一个问题的特定代码如下:

代码

### 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

代码产生以下输出:

enter image description here

否假定数据集具有新的列信息

#ID  Parent   Name    Info
$Data <<EOD
   1    NaN   Ant   1
   2      1   Ape   2
   3      1   Ass   2
   4      2   Bat   1
   5      2   Bee   1
   6      2   Cat   1
   7      3   Cod   1
   8      3   Cow   1
   9      3   Dog   1
  10      7   Eel   1
  11      7   Elk   1
  12      7   Emu   1
  13      9   Fly   1
  14      9   Fox   1
  15      4   Gnu   1
  16      1   Hen   2
  17     16   Hog   1
  18     12   Jay   1
  19     12   Owl   1
  20     15   Pig   2
  21     15   Pug   4
  22     12   Ram   1
  23     14   Rat   1
  24     12   Sow   1
  25      7   Yak   1
EOD

我想将info值= 1的节点染成黄色,将= 2的节点染成绿色,= 3的形状做成正方形而不是圆形。我已经为此努力了一段时间,我可以获得一些帮助。

1 个答案:

答案 0 :(得分:2)

颜色和形状都可以编码为数组。该数组必须与您期望的最大索引值一样大。在这里,我使用上面显示的数据和两个长度为4的数组来编码[圆形,圆形,正方形,正方形]和[黄色,绿色,黄色,绿色]

(?<=\w)!!

enter image description here