当将大数据集绘制为动画时,gnuplot会变慢

时间:2015-06-15 19:37:19

标签: performance file plot gnuplot

我正在试图用一个大文本文件制作一个“动画”的大量数据(1000个粒子的位置),其中包含如下脚本:

set terminal wxt size 1000,600
k=999999
N = 999
do for [i=0:k]{
plot for [j=0:N-1] "pos.txt" using 2*j+1:2*j+2  every ::2*i+1::2*i+1 ls 1 pt 7 ps 2 notitle

在文件中,每一行在我想要绘制的点的特定时间都有坐标X和Y.我正在使用every绘制每行中的所有数据,然后转到下一行。

输出类似于此(1000粒子移动)enter image description here

然而,绘图太慢了,我不知道我能做些什么才能让它更快地绘制。它每5秒或更长时间绘一行一次。该文件加权一些MB。我应该更换终端吗?还是我存储数据的方式?我认为当gnuplot加载一个大文件时可能会出现问题 一些粒子在模拟中消失,因此当索引line 14: warning: Skipping data file with no valid points(井2j + 1)超过粒子数时我也会得到错误j但我尝试制作它以便它读取粒子数每一次,它甚至更慢。非常感谢。

2 个答案:

答案 0 :(得分:3)

我怀疑gnuplot每次绘制时都会读取整个文件,相反读取相关行,然后是下一行,然后是下一行等。一种可能的策略是将粒子轨迹分成不同的文件,但是特别是它可以帮助删除plot for只需plot加上every的块选择,而不是选择粒子的列,而是让粒子位置在同一时间步长在同一个街区。

现在您的数据看起来像这样:

x1 y1 x2 y2 x3 y3 # Time step 1
x1 y1 x2 y2 x3 y3 # Time step 2

gnuplot需要为每个时间步粒子读取一次文件。如果按如下方式构造文件(注意块之间有一个空行):

# Time step 1
x1 y1
x2 y2
x3 y3

# Time step 2
x1 y1
x2 y2
x3 y3

然后你不需要plot for,而是通过在every中插入一个额外的分号来选择包含所有粒子的相应块:

set terminal wxt size 1000,600
k=999999
#N = 999 you don't need this anymore!
do for [i=0:k] {
plot "pos.txt" every :::i::i
}

上面的代码读取每个时间步的文件,而不是每一步粒子,并一次性绘制所有粒子。

答案 1 :(得分:2)

如果性能非常关键,您可以考虑使用完全不同的数据格式。尽管更改ASCII文件的格式会带来巨大的改进,但它会严重缩放,因为gnuplot必须始终从数据文件的开头进行扫描,以确定从哪里开始的位置。我做了一些测试,并绘制了我花了60s的前1000帧,而9000到10000点需要600s来绘制。

您需要一种数据格式,允许您在固定时间内搜索任何数据集。在我的论文中,我使用hdf5保存了所有实验数据(大数据集),然后您可以使用外部实用程序h5totxt来提取所需的数据集。这里,可以在不扫描整个文件的情况下计算所请求数据集的位置,并且访问时间与帧编号无关。

为了测试,我使用以下python脚本生成测试数据文件points.h5

from numpy import random
import h5py
P = random.normal(size=(10000,1000,2))
f = h5py.File('points.h5', 'w')
f.create_dataset('points', data=P)

用于绘图的gnuplot脚本是

set terminal wxt size 1000,600
k=9999
do for [i=0:9999]{
  plot sprintf("< h5totxt -s ' ' -x %d points.h5", i) using 1:2 ls 1 pt 7 ps 2 title sprintf("%d", i)
}

现在,无论您采用哪种帧(0-1000或9000-10000),1000帧的绘图都需要40秒。