繁体   English   中英

如何在 Gnuplot 中 plot 一个带有加权边的树/图/网络?

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

我正在按照此处的讨论在 gnuplot 中绘制一棵树( How to plot tree/graph/web data on gnuplot? )。 但是,我想包括树的边权重,即对于每个边,我都有一个代表边权重的数字(例如 10、20、30、40)。 下图以红色显示了我想要在 gnuplot 中 plot 的边缘权重(我使用 power point 添加了这个)。

谁能告诉我如何在 gnuplot 中使用权重计算 plot 边?

在此处输入图像描述

对于您在问题中提到的答案,我建议稍作改动。 假设顶点的坐标存储在文件pnts.dat ,如下所示:

0   5   10
1   20  20
2   15  15
3   30  30
4   40  10

在此,第一列记录相应的标签,而第二列和第三列分别包含x坐标和y坐标。

可以在单独的文件edges.dat边定义为:

0   1   30  0   1
1   2   40  0   -2
1   4   20  0   1
1   3   10  0   1

在这里,前两列包含点索引(它们指向pnts.dat的第一列)。 第三列记录特定边缘的权重。 最后,最后两列包含所生成的关联标签的x,y位移。

这样,Gnuplot脚本可能看起来像:

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
  1. loadEdges命令调用gawk ,以便为所有边缘生成对应的x / y坐标对(由空行分隔)
  2. loadWeights为每个边缘计算中间点,并在这些坐标上放置一个标签(考虑到所需的偏移量)

最后,获得: 在此处输入图片说明

另外,如果要向边缘添加箭头,则必须执行以下步骤:

  1. 添加箭头样式:

     set style arrow 1 head filled size screen 0.025,10,40 lc rgb "black" lw 2 
  2. 用向量的 更改命令

     loadEdges using 1:2:3:4 with vectors arrowstyle 1 notitle, \\ 

下图显示了最终结果:

在此处输入图片说明

这是最终的代码:

    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

这是一个类似于@ewcz 解决方案的建议,即使用带有 x,y 坐标的 ID 列表和使用两个 ID 的连接列表。 但是,具有以下差异:

  • 一个文件中的所有数据(在两个不同的块中,用索引寻址)
  • 没有awkgawkgnuplot-only解决方案,因此与平台无关。 查找列表是使用 gnuplot 创建的,类似于此答案
  • 个别 label 点之间的旋转角度dA和相对长度dR的偏移量( dR=0 :在连接器的中心, dR=-1 :在起点, dR=1 :在终点)。 因此,建议使用set size ratio -1 ,例如旋转 45 度在图形中视觉上是 45 度。

数据: 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

脚本:(适用于 gnuplot>=5.0.0,没有选项textbox它适用于 >=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

结果:

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM