Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用matplotlib打印大量点并耗尽内存_Python_Matplotlib_Large Data - Fatal编程技术网

Python 使用matplotlib打印大量点并耗尽内存

Python 使用matplotlib打印大量点并耗尽内存,python,matplotlib,large-data,Python,Matplotlib,Large Data,我有一个简单格式的大(~6GB)文本文件 x1 y1 z1 x2 y2 z2 ... 由于我可能会多次加载此数据,出于效率原因,我创建了一个np.memmap文件: X,Y,Z = np.memmap(f_np_mmap,dtype='float32',mode='r',shape=shape).T 我想做的是策划: plt.scatter(X, Y, color=custom_colorfunction(Z), alpha=.01, s=.0

我有一个简单格式的大(~6GB)文本文件

x1 y1 z1
x2 y2 z2
...
由于我可能会多次加载此数据,出于效率原因,我创建了一个
np.memmap
文件:

X,Y,Z = np.memmap(f_np_mmap,dtype='float32',mode='r',shape=shape).T
我想做的是策划:

plt.scatter(X, Y, 
           color=custom_colorfunction(Z), 
           alpha=.01, s=.001, marker='s', linewidth=0)
这对于较小的数据集非常有效。但是,对于这个较大的数据集,我的内存不足。我检查了
plt.scatter
是否占用了所有内存;我可以一步一步地通过
X,Y,Z
很好。有没有一种方法可以使画布“光栅化”,这样就不会耗尽内存?我不需要缩放和平移图像,它直接进入磁盘。我意识到我可以存储数据并绘制它,但我不确定如何使用自定义颜色贴图和alpha值来实现这一点。

类似这样的东西(很抱歉代码太长,大部分都是从标准
axes.axes.draw中复制的):

从操作员导入itemgetter
类生成器散点轴(matplotlib.axes.axes):
定义初始化(self,*args,**kwargs):
matplotlib.axes.axes.__初始化__(self,*args,**kwargs)
self.\u big\u data=无
def draw(自绘制,渲染器=无,inframe=无):
#从原始绘图复制(因此您仍然可以添加普通艺术家等)
如果渲染器为“无”:
渲染器=自身。\u缓存渲染器
如果渲染器为“无”:
raise RUNTIMERROR('未定义渲染器')
如果不是self.get_visible():
返回
渲染器。打开_组(“轴”)
locator=self.get\u axes\u locator()
如果定位器:
pos=定位器(自身、渲染器)
自我应用方面(pos)
其他:
self.apply_aspect()
艺术家=[]
artists.extend(self.collections)
Artisters.extend(self.patches)
艺术家.延伸(自我.线条)
艺术家。扩展(self.text)
扩展(self.artists)
如果self.axison而不是inframe:
如果是self.\u,则如下所示:
self.xaxis.set_zorder(0.5)
self.yaxis.set_zorder(0.5)
其他:
self.xaxis.set_zorder(2.5)
self.yaxis.set_zorder(2.5)
扩展([self.xaxis,self.yaxis])
如果不是我:
Artisters.append(self.title)
艺术家。附加(自我。\u左\u标题)
艺术家。附加(自我。\u右\u标题)
Artisters.extend(self.tables)
如果self.legend_uu不是无:
Artisters.append(self.legend_389;)
#框架围绕轴面片绘制边——我们
#将它们解耦,使补丁可以位于背景和背景中
#前景中的帧。
如果self.axison和self.\u frameon:
扩展(self.spines.itervalues())
如果self.figure.canvas.is_saving():
dsu=[(a.zorder,a)表示艺术家中的a]
其他:
dsu=[(a.zorder,a)表示艺术家中的a
如果不是a,则设置动画()
#如果后端支持合成,则将图像添加到dsu。
#否则,在不向dsu添加图像的情况下执行manaul合成。
如果len(self.images)0和dsu[0][0]<光栅化顺序):
renderer.start_光栅化()
dsu_光栅化=[l代表dsu中的l,如果l[0]<光栅化_zorder]
dsu=[l表示dsu中的l,如果l[0]>=光栅化\u zorder]
其他:
dsu_光栅化=[]
#该面片绘制背景矩形,即下面的框架
#我会画边的
如果self.axison和self.\u frameon:
self.patch.draw(渲染器)
如果_do_复合:
#制作合成图像混合alpha
#列表(mimage.Image,ox,oy)
zorder_images=[(im.zorder,im)表示self.images中的im
如果im.get_visible()]
zorder_images.sort(key=lambda x:x[0])
mag=渲染器。获取图像放大率()
ims=[(im.make_image(mag),0,0,im.get_alpha())用于z,im在zorder_图像中]
l、 b,r,t=self.bbox.extenses
宽度=mag*((圆形(r)+0.5)-(圆形(l)-0.5))
高度=mag*((圆(t)+0.5)-(圆(b)-0.5))
im=从图像(高度,
宽度,
(国际监测系统)
im.is_灰度=假
l、 b,w,h=self.bbox.bounds
#合成图像需要特殊的参数,这样它们就不会
#现在尊重z顺序
gc=renderer.new_gc()
gc.set\u clip\u矩形(self.bbox)
gc.set\u clip\u path(mttransforms.TransformedPath(
self.patch.get_path(),
self.patch.get_transform())
渲染器。绘制图像(gc、圆形(l)、圆形(b)、im)
gc.restore()
如果dsu被光栅化:
对于zorder,dsu中的a被光栅化:
a、 绘制(渲染器)
渲染器。停止网格化()
对于zorder,dsu中的a:
a、 绘制(渲染器)
############################    
#新比特
############################
如果self.\u big\u data不是无:
对于x、y、z在自身中。_大数据:
#将(单点)添加到轴
a=自散射(x,y,color='r',
alpha=1,s=10,marker='s',线宽=0)
#添加点,在Agg中,这将渲染+合成
a、 绘制(渲染器)
#将艺术家从轴上移除,不应让渲染人员知道
a、 删除()
#删除该艺术家以获得最佳效果
德拉
#######################
#结束新位
#######################    
#再次,从原始到清理
渲染器。关闭_组(“轴”)
self.\u cachedRenderer=渲染器
像这样使用它:

In [42]: fig = figure()

In [43]: ax = generator_scatter_axes(fig, [.1, .1, .8, .8])

In [44]: fig.add_axes(ax)
Out[44]: <__main__.generator_scatter_axes at 0x56fe090>

In [45]: ax._big_data = rand(500, 3)

In [46]: draw()
[42]中的
:图=图()
在[43]中:ax=发生器散射轴(图[1,1,8,8])
在[44]中:图添加轴(ax)
欧点
In [42]: fig = figure()

In [43]: ax = generator_scatter_axes(fig, [.1, .1, .8, .8])

In [44]: fig.add_axes(ax)
Out[44]: <__main__.generator_scatter_axes at 0x56fe090>

In [45]: ax._big_data = rand(500, 3)

In [46]: draw()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import _png
from itertools import izip

def main():
    # We'll be saving the figure's background, so let's make it transparent.
    fig, ax = plt.subplots(facecolor='none')

    # You'll have to know the extent of the input beforehand with this method.
    ax.axis([0, 10, 0, 10])

    # We need to draw the canvas before we start adding points.
    fig.canvas.draw()

    # This won't actually ever be drawn. We just need an artist to update.
    col = ax.scatter([5], [5], color=[0.1, 0.1, 0.1], alpha=0.3)

    for xy, color in datastream(int(1e6), chunksize=int(1e4)):
        col.set_offsets(xy)
        col.set_color(color)
        ax.draw_artist(col)

    save(fig, 'test.png')

def datastream(n, chunksize=1):
    """Returns a generator over "n" random xy positions and rgb colors."""
    for _ in xrange(n//chunksize):
        xy = 10 * np.random.random((chunksize, 2))
        color = np.random.random((chunksize, 3))
        yield xy, color

def save(fig, filename):
    """We have to work around `fig.canvas.print_png`, etc calling `draw`."""
    renderer = fig.canvas.renderer
    with open(filename, 'w') as outfile:
        _png.write_png(renderer._renderer.buffer_rgba(),
                       renderer.width, renderer.height,
                       outfile, fig.dpi)

main()
import numpy as np
from PIL import Image

def png_write(fig, filename):
    width, height = map(int, fig.get_size_inches() * fig.get_dpi())
    image = np.frombuffer(fig.canvas.tostring_argb(), dtype='uint8')
    image = image.reshape(width, height, 4)
    image = np.roll(image, -1, 2)
    Image.fromarray(image, 'RGBA').save(filename)