matplotlib MemoryError на pcolorfast - PullRequest
3 голосов
/ 12 декабря 2010

Проблема:

В настоящее время я загружаю данные столбцов из текстовых файлов в массивы, а затем строю их и сохраняю полученное изображение. Поскольку значения всегда будут лежать на одинаково разнесенной сетке, подходящее время для использования pcolorfast. Каждый массив обязательно квадратный, обычно между 1024x1024 и 8192x8192. В настоящее время меня интересует только эта работа до размеров 4096x4096 включительно. Это необходимо сделать для сотен файлов, и, хотя оно успешно завершает первое изображение, последующие изображения вылетают в MemoryError.

Неудачные решения:

Я гарантировал, согласно здесь , что у меня есть Hold = False в rc.

Ограничения:

Изображения должны быть сохранены с использованием всех значений 4096x4096 и не могут быть уменьшены до 1024x1024 (как предлагается здесь ).

Примечания:

После просмотра использования памяти на каждом этапе (создание пустого массива, загрузка значений, построение графика, сохранение) массив A все еще находится в памяти после завершения makeFrame. Требуется ли явный вызов для его удаления? Нужно ли явно удалять fig, или pylab позаботится об этом? Идеальная ситуация (вероятно, очевидная) состояла бы в том, чтобы использование памяти вернулось к тому же уровню, который был до вызова makeFrame ().

Любой совет очень ценится. Я пытался решить эту проблему в течение нескольких дней, поэтому не исключено, что я пропустил что-то очевидное. И очевидные решения будут захватывающими (если альтернативой будет то, что это более сложная проблема).

Пример текущего кода:


import numpy
import matplotlib
matplotlib.use("AGG")
import matplotlib.pylab as plt

def makeFrame(srcName, dstName, coloring, sideLength,
              dataRanges, delim, dpi):
    v,V,cmap = coloring
    n = sideLength
    xmin,xmax,ymin,ymax = dataRanges
    A = numpy.empty((n,n),float)
    dx = (xmax-xmin) / (n-1)
    dy = (ymax-ymin) / (n-1)

    srcfile = open(srcName,'rb')
    for line in srcfile:
        lineVals = line[:-1].split(delim)
        x = float(lineVals[0])
        y = float(lineVals[1])
        c = float(lineVals[2])

        #Find index from float value, adjust for rounding
        i = (x-xmin) / dx
        if (i - int(i) ) > .05: i += 1

        j = (y-ymin) / dy
        if (j - int(j) ) > .05: j += 1

        A[i,j] = c
    srcfile.close()
    print "loaded vals"

    fig = plt.figure(1)
    fig.clf()
    ax = fig.gca()
    ScalarMap = ax.pcolorfast(A, vmin = v, vmax = V, cmap = cmap)
    fig.colorbar(ScalarMap)
    ax.axis('image')
    fig.savefig(dstName, dpi = dpi)
    plt.close(1)
    print "saved image"

1 Ответ

2 голосов
/ 12 декабря 2010

Предостережения:

  • Там может быть лучший способ справиться с этой проблемой памяти, что я не знать о.
  • Я не смог воспроизвести это ошибка. Когда я использую matplotlib.cbook.report_memory() мой Использование памяти, кажется, выровняется как ожидается.

Несмотря на предостережения, я подумал, что упомяну общий дешевый метод решения проблем, вызванных отказом программы освободить память: используйте модуль multiprocessing , чтобы вызвать проблемную функцию в отдельном процессе , Дождитесь окончания функции, затем вызовите ее снова. Каждый раз, когда подпроцесс завершается, вы восстанавливаете память, которую он использовал.

Поэтому я предлагаю попробовать что-то вроде этого:

import matplotlib.cbook as mc
import multiprocessing as mp
import matplotlib.cm as cm

if __name__=='__main__':
    for _ in range(10):
        srcName='test.data'
        dstName='test.png'
        vmin = 0
        vmax = 5
        cmap = cm.jet
        sideLength = 500
        dataRanges = (0.0,1.0,0.0,1.0)
        delim = ','
        dpi = 72
        proc=mp.Process(target=makeFrame,args=(
            srcName,dstName,(vmin,vmax,cmap),sideLength,
            dataRanges,delim,dpi))
        proc.start()
        proc.join()
        usage=mc.report_memory()
        print(usage)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...