使用pcolormesh叠加绘制两个栅格图时触发MemoryError如何解决
问题原因
你遇到的内存错误是叠加两次超大分辨率pcolormesh图层导致的:单张(2914,3560)的栅格在pcolormesh渲染时需要为每个元素存储RGBA四通道float64数据,正好对应报错里的317MiB占用,叠加第二个带hatch填充的图层时,除了第二份RGBA数据外,hatch的矢量路径渲染还会产生额外的内存开销,超过阈值就触发了内存分配失败。
解决方案
- 合并非重叠区域,避免全量绘制两次图层
你第二个图层仅需要在z_disadvantage非NaN的区域显示带斜线填充的效果,无需绘制完整的全量矩阵,可以仅保留需要叠加的有效区域,其余部分全部mask,减少无效渲染的元素量。 - 降低数据精度
可视化场景不需要float64精度,在传入pcolormesh前将x、y、z矩阵都转为float32类型,内存占用直接减半:
z_conversion = z_conversion.astype(np.float32) z_disadvantage = z_disadvantage.astype(np.float32) x = x.astype(np.float32) y = y.astype(np.float32)
- 开启栅格化渲染
给pcolormesh添加rasterized=True参数,将矢量渲染转为和画布分辨率绑定的栅格渲染,不再为每个栅格元素单独存储矢量属性,你当前画布仅800*600分辨率,渲染开销会下降一个数量级,尤其适合带hatch的图层,修改后的代码示例如下:
def create_contour(x,y,z_conversion,z_disadvantage, title, unit): graphWidth = 800 graphHeight = 600 f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100) axes = f.add_subplot(111) axes.set_title(title) vmin_set = max(np.nanmin(z_conversion), np.nanmin(z_disadvantage)) vmax_set = min(np.nanmax(z_conversion), np.nanmax(z_disadvantage)) # 转float32减少内存 z_conversion = z_conversion.astype(np.float32) z_disadvantage = z_disadvantage.astype(np.float32) x = x.astype(np.float32) y = y.astype(np.float32) plt.pcolormesh(x, y, z_conversion, vmin=vmin_set, vmax=vmax_set, cmap = "Blues", shading='nearest', label='conversion', rasterized=True) plt.pcolormesh(x, y, np.ma.masked_where(np.isnan(z_disadvantage),z_disadvantage), vmin=vmin_set, vmax=vmax_set, cmap = "Blues", shading='nearest', label='disadvantage',hatch='/', rasterized=True) cbar = plt.colorbar() cbar.set_label(unit) plt.show()
- 提前降采样栅格
你的画布宽度仅800像素,原始3560列的栅格远高于显示分辨率,完全可以提前用scipy插值函数或者numpy切片降采样到1000*800左右的分辨率,元素量降为原来的1/10不到,可彻底解决内存问题。
内容的提问来源于stack exchange,提问作者K Bao
相关产品推荐
相关产品推荐

