散点图与海量数据

24 投票
3 回答
59885 浏览
提问于 2025-04-16 06:27

我想用Matplotlib来生成一个散点图,数据量非常大,大约有300万个点。实际上,我有3个维度相同的向量,我是这样来绘图的。

import matplotlib.pyplot as plt
import numpy as np
from numpy import *
from matplotlib import rc
import pylab
from pylab import * 
fig = plt.figure()
fig.subplots_adjust(bottom=0.2)
ax = fig.add_subplot(111)
plt.scatter(delta,vf,c=dS,alpha=0.7,cmap=cm.Paired)

其实没什么特别的。不过生成这个图的速度太慢了(我在我的MacBook Pro上,内存只有4GB,使用的是Python 2.7和Matplotlib 1.0)。有没有什么办法可以提高速度呢?

3 个回答

13

你可以试试 pyplot.hexbin 这个工具。它可以根据点的密度生成一种热力图,热力图是把数据分成几个区域,然后显示每个区域里有多少个点。

29

除非你的图形非常大,否则这300万个点中会有很多是重叠的。
(比如一个400x600的图片只有24万个点……)

所以最简单的方法就是从你的数据中随机抽取大约1000个点:

import random
delta_sample=random.sample(delta,1000)

然后就把这些点画出来。

例如:

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
import random

fig = plt.figure()
fig.subplots_adjust(bottom=0.2)
ax = fig.add_subplot(111)

N=3*10**6
delta=np.random.normal(size=N)
vf=np.random.normal(size=N)
dS=np.random.normal(size=N)

idx=random.sample(range(N),1000)

plt.scatter(delta[idx],vf[idx],c=dS[idx],alpha=0.7,cmap=cm.Paired)
plt.show()

alt text

或者,如果你需要更关注一些特殊的点(也就是离群点),那么你可以使用 np.histogram 来对数据进行分组,然后创建一个 delta_sample,这个样本会从每个分组中选出一些代表性的数据。

不过,使用 np.histogram 的时候,我觉得没有简单的方法可以把分组和单独的数据点联系起来。一个简单但不太精确的解决办法是,利用一个点在分组中的位置或者在分组边缘的位置,来代表这个分组里的点:

xedges=np.linspace(-10,10,100)
yedges=np.linspace(-10,10,100)
zedges=np.linspace(-10,10,10)
hist,edges=np.histogramdd((delta,vf,dS), (xedges,yedges,zedges))
xidx,yidx,zidx=np.where(hist>0)
plt.scatter(xedges[xidx],yedges[yidx],c=zedges[zidx],alpha=0.7,cmap=cm.Paired)
plt.show()

alt text

9

你可以参考这里展示的热力图方法here。在这个例子中,颜色代表的是每个区域里数据的数量,而不是dS数组的中位数值,不过这个改起来应该很简单。如果你感兴趣的话,后面我可以再详细讲讲。

撰写回答