绘制大量图像时 Matplotlib 分割错误

Pro*_*ala 5 python matplotlib segmentation-fault

我有一个将 3D numpy 数组绘制为图像堆栈的函数:

def plotImages( 
    prefix, F, slices,
    extent=None, zs = None, figsize=default_figsize, 
    cmap=default_cmap, interpolation=default_interpolation, vmin=None, vmax=None, cbar=False, 
    ):
    for ii,i in enumerate(slices):
        print " plotting ", i
        plt.figure( figsize=figsize )
        plt.imshow( F[i], origin='image', interpolation=interpolation, cmap=cmap, extent=extent, vmin=vmin, vmax=vmax )
        if cbar:
            plt.colorbar();
        plt.xlabel(r' Tip_x $\AA$')
        plt.ylabel(r' Tip_y $\AA$')
        if zs is None:
            plt.title( r"iz = %i" %i  )
        else:
            plt.title( r"Tip_z = %2.2f $\AA$" %zs[i]  )
        plt.savefig( prefix+'_%3.3i.png' %i, bbox_inches='tight' )
        plt.close()
Run Code Online (Sandbox Code Playgroud)

我在循环中调用此函数,用于约 20 个数据网格(3D numpy 数组),每个数据网格有约 50 个切片 => 它会生成~20 x ~50 = ~1000图像。

但在数百张图像之后,它崩溃了Segmentation fault (core dumped)。这个问题很难跟踪,因为它是随机出现的,并且需要很长的运行时间(10 分钟)才会崩溃。

我很确定问题出在 matplotlib (或 numpy ?) 内部,因为它在只有 matplotlib 函数的循环中间崩溃。

另外我认为这可能取决于内存使用情况(?)。我打开的程序越多,问题出现的越早。plt.close()当我开始清理内存(调用并在我的数据网格上)时,问题也减少了(出现得更晚)delete F。我在想它是否与垃圾收集或类似的东西有关?

  1. 您知道可能是什么问题吗?
  2. 您建议采取什么策略来追踪它?

编辑:我做了这个非常简单的人工示例,它重现了崩溃

import numpy as np
import matplotlib.pyplot as plt

default_figsize = (3,3)

def plotImages( prefix, F, figsize=default_figsize ):
    slices = range( len( F ) )
    for ii,i in enumerate(slices):
        print " plotting ", i
        plt.figure( figsize=figsize )
        plt.imshow( F[i], origin='image' )
        plt.title( r"iz = %i" %i  )
        plt.savefig( prefix+'_%3.3i.png' %i, bbox_inches='tight' )
        plt.close()


nx = 500
ny = 500
nz = 100
ng = 100

for i in range( ng ):
    F = np.random.randn( nz,ny,nx )
    print "NEW GRID ", i , " : ", np.shape(F)
    plotImages( "", F )
    del F
Run Code Online (Sandbox Code Playgroud)

出现Segmentation fault (core dumped)在网格 #12 切片 #54 之后,这意味着绘制了 11x100 + 54 = 1154 个图像之后

输出如下:

NEW GRID  12  :  (100, 500, 500)
 plotting  0
 plotting  1
 plotting  2
 .... # ommited lines here
 plotting  50
 plotting  51
 plotting  52
 plotting  53
 plotting  54
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)