如何通过指定 Gnuplot 脚本内的所有点来绘制数据而无需单独的文件?

发布于 2024-09-10 18:44:07 字数 167 浏览 4 评论 0 原文

我的程序生成调用 gnuplot 的 bash 脚本。我不想创建额外的文件来存储数据;有什么方法可以显式调用所有值吗?或者可能让 bash 创建一个临时文件。

类似的东西。

plot {(1,5),(2,10),(3,1)}

我正在寻找

My program generates bash scripts that call gnuplot. I don't want to have to make an extra file to store the data; is there any way I can explicitly call all of the values? Or possibly having bash make a temporary file.

Something like

plot {(1,5),(2,10),(3,1)}

is what I am looking for.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

海风掠过北极光 2024-09-17 18:44:07

您可以使用内联数据的语法 - 文件名 '-'

以下示例在 GIF 图像(bash 脚本)中生成一个简单的绘图:

gnuplot << EOF
set terminal gif
set output 'plot1.gif'
plot '-' using 1:2
        1 10
        2 20
        3 32
        4 40
        5 50
        e
EOF

You can use the syntax for inline data - filename '-'.

The following example produces a simple plot in a GIF image (bash script):

gnuplot << EOF
set terminal gif
set output 'plot1.gif'
plot '-' using 1:2
        1 10
        2 20
        3 32
        4 40
        5 50
        e
EOF
心不设防 2024-09-17 18:44:07

Gnuplot 5.0.1 数据块

main.gnuplot

$data << EOD
1 1
2 4
3 9
4 16
EOD

plot "$data" \
  with linespoints \
  title "my data"

转换为 PNG:

gnuplot -e 'set terminal png' -e 'set output "main.png"' main.gnuplot

输出:

在此处输入图像描述

此方法比 '-' 更通用,因为它使得更容易多次重复使用相同的数据,包括在同一个 plot 命令上:如何在单个绘图命令的 gnuplot 命令脚本中嵌入多个数据集?

版本 5 可在Ubuntu 15.04,或从源代码编译:https://askubuntu.com/a/684136/52975

对使用函数绘图时的 +++ 特殊文件名感兴趣。

在 Ubuntu 18.10、gnuplot 5.2 上测试。

Gnuplot 5.0.1 datablocks

main.gnuplot

$data << EOD
1 1
2 4
3 9
4 16
EOD

plot "$data" \
  with linespoints \
  title "my data"

Convert to PNG:

gnuplot -e 'set terminal png' -e 'set output "main.png"' main.gnuplot

Output:

enter image description here

This method is a bit more versatile than '-' as it makes it easier to reuse the same data multiple times, including on the same plot command: How to embed multiple datasets in a gnuplot command script for a single plot command?

Version 5 is available on Ubuntu 15.04, or compile from source with: https://askubuntu.com/a/684136/52975

You may also be interested in the + and ++ special file names when plotting with functions.

Tested on Ubuntu 18.10, gnuplot 5.2.

烟酒忠诚 2024-09-17 18:44:07

使用带有管道的 shell 的示例,

gnuplot -p <(echo -e 'plot "-"\n1 1\ne')

Example from using shell with pipeline,

gnuplot -p <(echo -e 'plot "-"\n1 1\ne')
那片花海 2024-09-17 18:44:07

使用 gnuplot 绘制一行 ping 图形

抱歉,不是light(361 个字符):

gnuplot -p -e "set xdata time;set timefmt '%s';set xrange [ '$(date +%s)' : '$(date -d 'now +30 seconds' +%s)' ];plot '-' using 1:2 with line title 'ping google';" < <(( ping -c 30 -n google.com| sed -u 's/^64.*time=\([0-9.]\+\) .*$/\1/p;d' | tee >(sed -u 's/.*/now/'| stdbuf -oL date -f - +d%s)) | sed -u 'N;s/\n/ /;s/\([0-9.]\+\) d\([0-9]\+\) */\2 \1/;s/d//')

运行此行将使您的终端停留 30 秒,然后在屏幕上绘制一个图表,显示过去 30 秒到 google.com 的 ping 延迟。

同一行可以像这样分割(也可行):

gnuplot -p -e "
    set xdata time;
    set timefmt '%s';
    set xrange [ '$(
        date +%s
      )' : '$(
        date -d 'now +30 seconds' +%s
      )' ];
    plot '-' using 1:2 with line title 'ping google';
    " < <((
    ping -c 30 -n google.com |
        sed -u 's/^64.*time=\([0-9.]\+\) .*$/\1/p;d' |
        tee >(sed -u 's/.*/now/'| stdbuf -oL date -f - +d%s)) |
    sed -u 'N;s/\n/ /;s/\([0-9.]\+\) d\([0-9]\+\) */\2 \1/;s/d//'
)

但这不打印值!

所以我添加了一些字节:

gnuplot -p -e "set xdata time;set timefmt '%s';set xrange [ '$(date +%s)' : '$(date -d 'now +30 seconds' +%s)' ];plot '-' using 1:2 with line title 'ping google';" < <(( ping -c 30 -n google.com| sed -u 's/^64.*time=\([0-9.]\+\) .*$/\1/p;d' | tee >(sed -u 's/.*/now/'| stdbuf -oL date -f - +d%s)  ) | sed -u 'N;s/\n/ /;s/\([0-9.]\+\) d\([0-9]\+\) */\2 \1/;s/d//' | tee >(printf "%(%T)T %s\n" $(</dev/stdin) | column -c $COLUMNS >&2 ))

这可能会创建一个像这样的窗口:

在此处输入图像描述

并同时在终端上打印:

17:58:53 19.6   17:59:00 124    17:59:07 159    17:59:13 194    17:59:19 17.1
17:58:54 18.7   17:59:02 19.4   17:59:08 20.3   17:59:14 16.8   17:59:20 20.0
17:58:55 17.9   17:59:03 180    17:59:09 76.4   17:59:15 48.9   17:59:21 192
17:58:57 115    17:59:04 186    17:59:10 226    17:59:16 221    17:59:22 17.1
17:58:58 18.5   17:59:05 16.8   17:59:11 109    17:59:17 19.0
17:58:59 17.0   17:59:06 184    17:59:12 18.8   17:59:18 18.7

重写分割:

gnuplot -p -e "
    set xdata time;
    set timefmt '%s';
    set xrange [ '$(date +%s)' : '$(date -d 'now +30 seconds' +%s)' ];
    plot '-' using 1:2 with line title 'ping google';" < <(
  (
      ping -c 30 -n google.com |
        sed -u 's/^64.*time=\([0-9.]\+\) .*$/\1/p;d' |
        tee >(sed -u 's/.*/now/'| stdbuf -oL date -f - +d%s)
  ) | sed -u 'N;s/\n/ /;s/\([0-9.]\+\) d\([0-9]\+\) */\2 \1/;s/d//' |
  tee >(printf "%(%T)T %s\n" $(</dev/stdin) |
  column -c $COLUMNS >&2 )
)

One line ping graph with gnuplot

Sorry, it's not light (361 characters):

gnuplot -p -e "set xdata time;set timefmt '%s';set xrange [ '$(date +%s)' : '$(date -d 'now +30 seconds' +%s)' ];plot '-' using 1:2 with line title 'ping google';" < <(( ping -c 30 -n google.com| sed -u 's/^64.*time=\([0-9.]\+\) .*$/\1/p;d' | tee >(sed -u 's/.*/now/'| stdbuf -oL date -f - +d%s)) | sed -u 'N;s/\n/ /;s/\([0-9.]\+\) d\([0-9]\+\) */\2 \1/;s/d//')

Running this line will hold your terminal for 30 seconds, than plot on screen a graph presenting ping delay to google.com on last 30 seconds.

The same line could be splitted like this (workable too):

gnuplot -p -e "
    set xdata time;
    set timefmt '%s';
    set xrange [ '$(
        date +%s
      )' : '$(
        date -d 'now +30 seconds' +%s
      )' ];
    plot '-' using 1:2 with line title 'ping google';
    " < <((
    ping -c 30 -n google.com |
        sed -u 's/^64.*time=\([0-9.]\+\) .*$/\1/p;d' |
        tee >(sed -u 's/.*/now/'| stdbuf -oL date -f - +d%s)) |
    sed -u 'N;s/\n/ /;s/\([0-9.]\+\) d\([0-9]\+\) */\2 \1/;s/d//'
)

But this don't print values!

So i've added some few bytes:

gnuplot -p -e "set xdata time;set timefmt '%s';set xrange [ '$(date +%s)' : '$(date -d 'now +30 seconds' +%s)' ];plot '-' using 1:2 with line title 'ping google';" < <(( ping -c 30 -n google.com| sed -u 's/^64.*time=\([0-9.]\+\) .*$/\1/p;d' | tee >(sed -u 's/.*/now/'| stdbuf -oL date -f - +d%s)  ) | sed -u 'N;s/\n/ /;s/\([0-9.]\+\) d\([0-9]\+\) */\2 \1/;s/d//' | tee >(printf "%(%T)T %s\n" $(</dev/stdin) | column -c $COLUMNS >&2 ))

This may create a window like this:

enter image description here

And simultaneously print on terminal:

17:58:53 19.6   17:59:00 124    17:59:07 159    17:59:13 194    17:59:19 17.1
17:58:54 18.7   17:59:02 19.4   17:59:08 20.3   17:59:14 16.8   17:59:20 20.0
17:58:55 17.9   17:59:03 180    17:59:09 76.4   17:59:15 48.9   17:59:21 192
17:58:57 115    17:59:04 186    17:59:10 226    17:59:16 221    17:59:22 17.1
17:58:58 18.5   17:59:05 16.8   17:59:11 109    17:59:17 19.0
17:58:59 17.0   17:59:06 184    17:59:12 18.8   17:59:18 18.7

Re-written splitted:

gnuplot -p -e "
    set xdata time;
    set timefmt '%s';
    set xrange [ '$(date +%s)' : '$(date -d 'now +30 seconds' +%s)' ];
    plot '-' using 1:2 with line title 'ping google';" < <(
  (
      ping -c 30 -n google.com |
        sed -u 's/^64.*time=\([0-9.]\+\) .*$/\1/p;d' |
        tee >(sed -u 's/.*/now/'| stdbuf -oL date -f - +d%s)
  ) | sed -u 'N;s/\n/ /;s/\([0-9.]\+\) d\([0-9]\+\) */\2 \1/;s/d//' |
  tee >(printf "%(%T)T %s\n" $(</dev/stdin) |
  column -c $COLUMNS >&2 )
)
长安忆 2024-09-17 18:44:07

解决方案是使用数组和参数线。

X="0.1 0.2 0.3 0.4 0.5"
Y="-1  0   2   4   8"

set parametric
set trange [1:words(X)]; set samples words(X)
plot (0+word(X,int(t))),(0+word(Y,int(t))) 

输出

来源:https://groups.google.com/d/msg/comp.graphics.apps.gnuplot/UdiiC2cBQNo/xEyj6i7Y910J

Solution is using arrays and parametric lines.

X="0.1 0.2 0.3 0.4 0.5"
Y="-1  0   2   4   8"

set parametric
set trange [1:words(X)]; set samples words(X)
plot (0+word(X,int(t))),(0+word(Y,int(t))) 

output

source: https://groups.google.com/d/msg/comp.graphics.apps.gnuplot/UdiiC2cBQNo/xEyj6i7Y910J

半暖夏伤 2024-09-17 18:44:07

10 年后...

您可以直接在 gnuplot 中编写类似的内容:

plot "< ./format.sh '{(1,5),(2,10),(3,1)}'"

其中 format.sh 是本地文件中的一个非常简单的脚本(记得给它 exec 权限):

#!/bin/bash
echo "$1" | sed 's:^..\(.*\)..$:\1:' | sed 's:),(:\n:g' | sed 's:,: :g'

它是如何工作的?

三个 sed 命令执行以下操作:

  1. 分别删除第一个和最后两个字符 {(})
  2. 更改序列 ) ,( 换行符
  3. 将剩余的 , 更改为空格

因此:

$ ./format.sh '{(1,5),(2,10),(3,1)}'
1 5
2 10
3 1

gnuplot plot " 语法杠杆在 popen 上运行 command< /code> 在 shell 中捕获输出并即时绘制它在其他情况下也非常有用。

10 years later...

You can write something like this directly in gnuplot:

plot "< ./format.sh '{(1,5),(2,10),(3,1)}'"

where format.sh is a pretty simple script in a local file (remember to give it exec permissions):

#!/bin/bash
echo "$1" | sed 's:^..\(.*\)..$:\1:' | sed 's:),(:\n:g' | sed 's:,: :g'

How does it works?

The three sed commands do the following:

  1. drops the first and last two characters, respectively {( and })
  2. changes the sequence ),( to a newline
  3. changes the remaining , to spaces

So:

$ ./format.sh '{(1,5),(2,10),(3,1)}'
1 5
2 10
3 1

The gnuplot plot "< command" syntax levers on popen to run command in a shell, capture the output and plot it on the fly. It can be pretty useful also in other circumstances.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文