GNUPlot:动画标签

时间:2014-09-03 05:45:32

标签: gnuplot

我的问题,从我之前的问题开始,现在是这样的:我有一个粒子在一个平面上移动,现在我想要一个侧面的盒子,它表示粒子在XY中的位置及其速度。我尝试过使用标签,但最终会相互重叠。

这是一个非常粗糙的草图"我希望看到的内容:

    +------------------------------------------+
    |         +-----------+                    |
    |         |           |       t = 2        |
    |         | PLOT HERE |  x = 0    y = 1    |
    |         |           |  vx = 2   vy = 3   |
    |         +-----------+                    |
    +------------------------------------------+

这些数字在每一帧都会发生变化。我已经能够为标题制作动画,但标签似乎不同。

我当前的代码看起来非常像GNUPlot - Plot 2D datapoints as MPEG中的答案,但有一些小的风格修改,我删除了标题。我可以生成只是XY坐标的数据,这就是我现在使用的。

我也可以制作类似的东西(这些是随机点,只是为了说明)

 #X      Y      t       vx     vy
  0.00   1.00   0.0     0.0   6.28
  0.01   0.01   0.01    1.0   6.00

用于制作动画标签。

1 个答案:

答案 0 :(得分:2)

从数据文件中放置标签的一种好方法是使用labels绘图样式。但是,将标签放置在实际绘图区域之外会有一些困难,因为这些点和标签通常会被剪裁。

既然你正在使用stats来修复x和yrange,我就是这样做的:

  • 设置固定的右边距,例如set rmargin 20。这使用了20个字符宽度的右边距。您也可以使用set rmargin at screen 0.8之类的绝对坐标,但由于您需要边距来放置标签,因此字符单元似乎是合适的。

  • 使用绘图区域的右上角作为参考点(STATS_max_x, STATS_max_y)并使用offset参数移动标签并再次移动一些字符宽度。

因此,完整的脚本可能如下所示:

# calculate the number of points
stats 'file.txt' using 1:2 nooutput

# if you want to have a fixed range for all plots
set xrange [STATS_min_x:STATS_max_x]
set yrange [STATS_min_y:STATS_max_y]

set terminal pngcairo size 800,400
outtmpl = 'output%07d.png'

v_label(x, y) = sprintf('vx = %.2f  vy = %.2f', x, y)
c_label(x, y) = sprintf('x = %d  y = %d', x, y)
t_label(t) = sprintf('t = %.2f', t)

set rmargin 20

do for [i=0:STATS_records-1] {
    set output sprintf(outtmpl, i)
    plot 'file.txt' every ::::i with lines title sprintf('n = %d', i),\
         '' every ::i::i using (STATS_max_x):(STATS_max_y):(t_label($3)) with labels offset char 11,-5 notitle,\
         '' every ::i::i using (STATS_max_x):(STATS_max_y):(c_label($1, $2)) with labels offset char 11,-6.5 notitle,\
         '' every ::i::i using (STATS_max_x):(STATS_max_y):(v_label($4, $5)) with labels offset char 11,-8 notitle
}

set output

Script output for t=0.01

请注意,rmarginoffset设置取决于终端,终端大小,字体和字体大小。对于更好的标签放置,您可以考虑单独放置vxvy标签,并可能更改其对齐方式。

或者,在每次迭代中,您都可以从数据文件中提取当前行并手动设置标签。但是,这需要您使用外部工具来提取行:

do for [i=0:STATS_records-1] {
    line = system(sprintf("sed -n %dp file.txt", i+2))
    set label 1 at screen 0.9, screen 0.9 sprintf("t = %.2f", real(word(line, 3)))
    set label 2 at screen 0.9, screen 0.88 sprintf("x = %.2f y = %.2f", real(word(line, 1)), real(word(line, 2)))
    plot 'file.txt' every ::::i with lines title sprintf('n = %d', i)
}

我不知道哪种变体更适合你。我使用i+2作为行号来跳过已注释的标题行,该标题行不会自动检测到。通过使用标签(set label 1)标记,您可以确保覆盖旧标签。