大数据在pyplot中出现内存错误
我刚开始学习Python和编程。我想用Python绘制一个方向图。我有很多点(大约120万个)在一个平面上,每个点都属于一个聚类。每个聚类应该有不同的颜色。目前我做的是给每个聚类分配一种颜色,然后在每个点上画一个填充的圆圈。我尝试分部分进行,先为不同的段创建图,然后用混合的方法把它们合在一起。这是我做的部分代码:(sn是点的总数,label是聚类的数组,表示聚类编号,xcoor和ycoor是点的坐标)
pylab.xlim([0,250])
pylab.ylim([0,100])
plt.savefig("HK pickle.png")
for l in range (1, 20):
for j in range(int((float(sn)/80)*(l-1)), int((float(sn)/80)*(l))):
overlay = Image.open("HK pickle.png")
c = label[j] % 8
if c == 0:
circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0.5, 0, 0))
elif c == 1:
circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (1, 0, 0))
elif c == 2:
circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0, 0.5, 0))
elif c == 3:
circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0, 1, 0))
elif c == 4:
circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0, 0, 0.5))
elif c == 5:
circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0, 0 ,1))
elif c == 6:
circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0.5, 0.5 ,0))
elif c == 7:
circle1 = plt.Circle((float(xcoor[j]), float(ycoor[j])), 0.05, color = (0.5, 0 ,0.5))
fig = plt.gcf()
fig.gca().add_artist(circle1)
del circle1
plt.savefig("HK pick.png")
del fig
back = Image.open("HK pick.png")
comp = Image.blend(back, overlay, 0.5)
comp.save("HK pickle.png", "PNG")
del comp
pylab.xlim([0,250])
pylab.ylim([0,100])
plt.savefig("HK plots.png")
但是,这导致了以下错误:
fig.gca().add_artist(circle1)
File "C:\Python27\lib\site-packages\matplotlib\axes.py", line 1404, in add_artist
self.artists.append(a)
MemoryError
错误出现在第11行。我一直在同时查看任务管理器,当出现内存错误时,它仍然有将近3GB的可用内存。请帮我解决这个问题。
我对这些还很陌生,不知道我提供的信息是否足够。如果你需要更多信息,请告诉我。
2 个回答
0
如果你在使用32位的操作系统或者运行的是32位的Python,那么处理大数据集会比较困难(安装64位的Python、numpy、matplotlib等可能会解决这个问题)。
不过,我建议你先尝试用较低的分辨率来绘制你的图像,看看这样是否能满足你的需求(结果可能会“足够好”)。比如,我建议你把这个j
的循环改成类似下面的代码:
for j in np.linspace(int((float(sn)/80)*(l-1)), int((float(sn)/80)*(l), num=20):
j = int(j)
这样你就能得到20个j
的值,这些值在你的范围内,但不是每个整数值。注意,你需要把j
转换成int
类型,因为它可能是np.float
类型!
其他的风格建议在这个时候可能不太有用,但一般来说,你不需要频繁使用del
,因为Python有一个很好的垃圾回收机制,会自动帮你处理这些。你还可以把限制条件放在循环外面,这样可能会让调试变得更简单:
start_j = int((float(sn)/80)*(l-1)))
end_j = int((float(sn)/80)*(l))
for j in np.linspace(start_j, end_j, num=20):
etc.
1
你可以试试用 scatter
这个方法,并加上一个选项 rasterized=True
,这样可以把所有的矢量图形转换成一个光栅图像(这样会占用更少的内存)。
像这样:
colors_lst = [ ... your tuples ...]
color = map(lambda x: colors_lst[x % 8], labels)
ax.scatter(xcoord, ycoord, c = colors, rasterized=True)
我觉得这可以替代你大部分的代码。