用python(5GB)绘制x轴偏移的大文件

用python(5GB)绘制x轴偏移的大文件,python,numpy,matplotlib,figure,Python,Numpy,Matplotlib,Figure,我正在尝试使用python和matplotlib绘制一个非常大的文件(~5GB)。我能够在内存中加载整个文件(机器中的可用总容量为16 GB),但当我使用simple imshow绘制它时,我遇到了分段错误。这是最有可能的ulimit,我已经设置为15000,但我不能设置更高。我得出的结论是,我需要批量绘制数组,因此我编写了一个简单的代码来实现这一点。我的主要目的是,当我绘制一批大数组时,x坐标总是从0开始,我无法覆盖图像以创建最终的大数组。如果你有任何建议,请告诉我。此外,由于管理权限,我无法

我正在尝试使用python和matplotlib绘制一个非常大的文件(~5GB)。我能够在内存中加载整个文件(机器中的可用总容量为16 GB),但当我使用simple imshow绘制它时,我遇到了分段错误。这是最有可能的ulimit,我已经设置为15000,但我不能设置更高。我得出的结论是,我需要批量绘制数组,因此我编写了一个简单的代码来实现这一点。我的主要目的是,当我绘制一批大数组时,x坐标总是从0开始,我无法覆盖图像以创建最终的大数组。如果你有任何建议,请告诉我。此外,由于管理权限,我无法在此计算机上安装像“Image”这样的新软件包。下面是一个代码示例,它读取数组的前12行并绘制3个图

import os
import sys
import scipy
import numpy as np
import pylab as pl
import matplotlib as mpl
import matplotlib.cm as cm
from optparse import OptionParser
from scipy import fftpack
from scipy.fftpack import *
from cmath import *
from pylab import *
import pp
import fileinput
import matplotlib.pylab as plt
import pickle

def readalllines(file1,rows,freqs):
    file = open(file1,'r')
    sizer = int(rows*freqs)
    i = 0
    q = np.zeros(sizer,'float')
    for i in range(rows*freqs):
        s =file.readline()
        s = s.split()
        #print s[4],q[i]
        q[i] = float(s[4])
        if i%262144 == 0:
            print '\r ',int(i*100.0/(337*262144)),'  percent complete',
        i += 1
    file.close()
    return q

parser = OptionParser()
parser.add_option('-f',dest="filename",help="Read dynamic spectrum from FILE",metavar="FILE")
parser.add_option('-t',dest="dtime",help="The time integration used in seconds, default 10",default=10)
parser.add_option('-n',dest="dfreq",help="The bandwidth of each frequency channel in Hz",default=11.92092896)
parser.add_option('-w',dest="reduce",help="The chuncker divider in frequency channels, integer default 16",default=16)
(opts,args) = parser.parse_args()
rows=12
freqs = 262144

file1 = opts.filename

s = readalllines(file1,rows,freqs)
s = np.reshape(s,(rows,freqs))
s = s.T
print s.shape
#raw_input()

#s_shift = scipy.fftpack.fftshift(s)


#fig = plt.figure()

#fig.patch.set_alpha(0.0)
#axes = plt.axes()
#axes.patch.set_alpha(0.0)
###plt.ylim(0,8)

plt.ion()

i = 0
for o in range(0,rows,4):

    fig = plt.figure()
    #plt.clf()

    plt.imshow(s[:,o:o+4],interpolation='nearest',aspect='auto', cmap=cm.gray_r, origin='lower')
    if o == 0:
        axis([0,rows,0,freqs])
    fdf, fdff = xticks()
    print fdf
    xticks(fdf+o)
    print xticks()
    #axis([o,o+4,0,freqs])
    plt.draw()

    #w, h = fig.canvas.get_width_height()
    #buf = np.fromstring(fig.canvas.tostring_argb(), dtype=np.uint8)
    #buf.shape = (w,h,4)

    #buf = np.rol(buf, 3, axis=2)
    #w,h,_ = buf.shape
    #img = Image.fromstring("RGBA", (w,h),buf.tostring())

    #if prev:
    #    prev.paste(img)
    #    del prev
    #prev = img
    i += 1
pl.colorbar()
pl.show()

我认为您只是缺少了
plt.imshow
中的
extent=(左、右、下、上)
关键字参数

x = np.random.randn(2, 10)
y = np.ones((4, 10))
x[0] = 0  # To make it clear which side is up, etc
y[0] = -1

plt.imshow(x, extent=(0, 10, 0, 2))
plt.imshow(y, extent=(0, 10, 2, 6))
# This is necessary, else the plot gets scaled and only shows the last array
plt.ylim(0, 6)
plt.colorbar()
plt.show()

如果在图形链中的某个位置上绘制任何超过2千像素的阵列,将以某种方式对图像进行下采样,以便在显示器上显示。我建议以一种受控的方式进行下采样,比如

data = convert_raw_data_to_fft(args) # make sure data is row major
def ds_decimate(row,step = 100):
    return row[::step]
def ds_sum(row,step):
    return np.sum(row[:step*(len(row)//step)].reshape(-1,step),1)
# as per suggestion from tom10 in comments
def ds_max(row,step): 
    return np.max(row[:step*(len(row)//step)].reshape(-1,step),1)
data_plotable = [ds_sum(d) for d in data] # plug in which ever function you want

或者。

打印图像时,Matplotlib的内存效率非常低。它会创建几个全分辨率中间阵列,这可能就是程序崩溃的原因

一种解决方案是在将图像输入matplotlib之前对其进行降采样,正如@tcaswell所建议的那样


我还编写了一些包装器代码,根据屏幕分辨率自动进行下采样。如果有用的话,它在。它还有一个优点,即图像可以动态重新采样,因此您仍然可以在需要时平移和缩放,而不牺牲分辨率。

为什么您要将整个文件读取到内存中,而不是只提取所需的信息?您的程序需要文件的每一位吗?或者更确切地说,你为什么要这样做?还有,你的循环有点扭曲,你不应该在一个for循环中做i+=1,而不是i。另外,如果你在300ppi显示器上以每个样本一个像素的方式绘制,方向上有262k个样本,它需要873英寸宽的显示器才能看到每个像素。在这种情况下试图绘制原始数据是毫无意义的。如果你只花1毫秒来观察每个像素,你将花350小时来检查你的数据。相反,你应该尝试对数据进行预处理,以提取出你感兴趣的各种特征,并以人脑可以处理的简化方式查看它们。如果有人帮助我如何在一个图形中相邻绘制阵列的两个部分,我想我可以解决这个问题。因此,我可以从337中加载4行,然后绘制另4行,并将它们相邻地绘制在前面的行旁边。+1:用于以受控方式处理下采样。就个人而言,我会绘制封套(也就是说,每组10000个点的最大值和最小值)和可能的差异封套,因为OP是在寻找异常值,但你的基本方法是正确的,imho。