【问题标题】:Draw process tree with gnuplot (change node colors and shapes)使用 gnuplot 绘制进程树(更改节点颜色和形状)
【发布时间】:2020-07-07 08:11:20
【问题描述】:

我想出了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

代码产生以下输出:

不假设数据集有新的列信息

#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

我想让节点的信息值 = 1 为黄色,= 2 为绿色,= 3 形状为正方形而不是圆形。我已经为此苦苦挣扎了一段时间,我可以得到一些帮助。

【问题讨论】:

    标签: gnuplot


    【解决方案1】:

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

    # put datablock into strings
    IDs = Parents = Names = Shapes = ''
    set table $Dummy
        plot $Data u (IDs = IDs.strcol(1).' '): \
                     (Parents = Parents.strcol(2).' '): \
                     (Names = Names.strcol(3).' '): \
                     (Shapes = Shapes.strcol(4).' ') 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 % 2s", n, XPos(n), Level(n), word(Names,j), word(Shapes,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
    
    
    array shape[4] = [ 6, 6, 4, 4 ]        # pointtype 6 = circle, pointtype 4 = square
    array color[4] = [ 0xeeee00, 0xccffcc, 0xeeee00, 0xccffcc ]
    
    plot $Tree u 2:3:(dx($1)):(dy($1)) w vec nohead ls -1 not,\
            '' u 2:3:(shape[$5]+1):(color[$5]) w p pt variable ps 6 lc rgb variable not, \
            '' u 2:3:(shape[$5]) w p pt variable ps 6 lw 1.5 lc rgb "black" not, \
            '' u 2:3:4 w labels offset 0,0.1 center not
    ### end of code
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多