我在这里遇到了一个问题(我的 RAM):它无法保存我想要绘制的数据。我确实有足够的高清空间。有什么解决方案可以避免我的数据集出现这种“阴影”吗?
具体来说,我处理数字信号处理,我必须使用高采样率。我的框架(GNU Radio)以二进制形式保存值(以避免使用过多的磁盘空间)。我打开它。之后我需要绘图。我需要绘图可缩放和交互。这是一个问题。
是否有任何优化潜力,或者其他可以处理更大数据集的软件/编程语言(如 R 左右)?实际上我想要更多的数据在我的情节中。但是我没有使用其他软件的经验。 GNUplot 失败,采用与以下类似的方法。我不知道 R(喷气机)。
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import struct
"""
plots a cfile
cfile - IEEE single-precision (4-byte) floats, IQ pairs, binary
txt - index,in-phase,quadrature in plaintext
note: directly plotting with numpy results into shadowed functions
"""
# unpacking the cfile dataset
def unpack_set(input_filename, output_filename):
index = 0 # index of the samples
output_filename = open(output_filename, 'wb')
with open(input_filename, "rb") as f:
byte = f.read(4) # read 1. column of the vector
while byte != "":
# stored Bit Values
floati = struct.unpack('f', byte) # write value of 1. column to a variable
byte = f.read(4) # read 2. column of the vector
floatq = struct.unpack('f', byte) # write value of 2. column to a variable
byte = f.read(4) # next row of the vector and read 1. column
# delimeter format for matplotlib
lines = ["%d," % index, format(floati), ",", format(floatq), "\n"]
output_filename.writelines(lines)
index = index + 1
output_filename.close
return output_filename.name
# reformats output (precision configuration here)
def format(value):
return "%.8f" % value
# start
def main():
# specify path
unpacked_file = unpack_set("test01.cfile", "test01.txt")
# pass file reference to matplotlib
fname = str(unpacked_file)
plt.plotfile(fname, cols=(0,1)) # index vs. in-phase
# optional
# plt.axes([0, 0.5, 0, 100000]) # for 100k samples
plt.grid(True)
plt.title("Signal-Diagram")
plt.xlabel("Sample")
plt.ylabel("In-Phase")
plt.show();
if __name__ == "__main__":
main()
像 plt.swap_on_disk() 这样的东西可以将这些东西缓存在我的 SSD 上;)
最佳答案
因此,您的数据并没有那么大,而且您在绘制数据时遇到问题的事实表明这些工具存在问题。 Matplotlib 有很多选项,输出很好,但它是一个巨大的内存 pig ,它从根本上假设你的数据很小。但是还有其他选择。
例如,我使用以下代码生成了一个 20M 数据点文件“bigdata.bin”:
#!/usr/bin/env python
import numpy
import scipy.io.numpyio
npts=20000000
filename='bigdata.bin'
def main():
data = (numpy.random.uniform(0,1,(npts,3))).astype(numpy.float32)
data[:,2] = 0.1*data[:,2]+numpy.exp(-((data[:,1]-0.5)**2.)/(0.25**2))
fd = open(filename,'wb')
scipy.io.numpyio.fwrite(fd,data.size,data)
fd.close()
if __name__ == "__main__":
main()
这会生成一个大小约为 229MB 的文件,并不是那么大;但是你已经表示你想去更大的文件,所以你最终会达到内存限制。
让我们首先关注非交互式情节。首先要意识到的是,在每个点都有字形的矢量图将是一场灾难——对于 20 M 点中的每一个点,其中大部分无论如何都会重叠,试图渲染小十字或圆圈或其他东西正在发生成为一场灾难,生成大量文件并花费大量时间。我认为这就是默认情况下下沉 matplotlib 的原因。
Gnuplot 可以轻松解决这个问题:
gnuplot> set term png
gnuplot> set output 'foo.png'
gnuplot> plot 'bigdata.bin' binary format="%3float32" using 2:3 with dots
甚至可以让 Matplotlib 谨慎行事(选择光栅后端,并使用像素来标记点):
#!/usr/bin/env python
import numpy
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
datatype=[('index',numpy.float32), ('floati',numpy.float32),
('floatq',numpy.float32)]
filename='bigdata.bin'
def main():
data = numpy.memmap(filename, datatype, 'r')
plt.plot(data['floati'],data['floatq'],'r,')
plt.grid(True)
plt.title("Signal-Diagram")
plt.xlabel("Sample")
plt.ylabel("In-Phase")
plt.savefig('foo2.png')
if __name__ == "__main__":
main()
现在,如果您想进行交互,您将不得不将要绘制的数据分箱,并即时放大。我不知道有任何 python 工具可以帮助您临时完成这项工作。
另一方面,绘制大数据是一项非常常见的任务,并且有一些工具可以胜任这项工作。 Paraview是我个人最喜欢的,VisIt是另一个。它们都主要用于 3D 数据,但特别是 Paraview 也可以处理 2d,并且非常具有交互性(甚至具有 Python 脚本界面)。唯一的技巧是将数据写入 Paraview 可以轻松读取的文件格式。
关于python - 具有约 2000 万个样本点和千兆字节数据的交互式大图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5854515/