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