如何在Python中绘制三百万个圆形

3
我有一个包含许多圆形(每个圆形都有x、y和od属性)的数据集,大约有3百万个,存储在pandas dataframe中。我想将它们叠加在一起以可视化模式。
我之前用较小的数据集(约15k个圆形)做过这个操作,但现在似乎出现了问题(内存使用量在几十万个圆形时就已经达到了16GB)。
df是dataframe,plt是matplotlib.pyplot。
ax2=plt.gca(xlim=(-.25,.25),ylim=(-0.25,0.25))

for i,row in df.iterrows():
    x=row.X_delta
    y=row.Y_delta
    od=float(row.OD)
    circle=plt.Circle((x,y),od/2,color='r',fill=False,lw=5,alpha=0.01)
    ax2.add_artist(circle)

有没有更节约内存的方法来完成这个操作?

7
为什么您想要画 300 万个圆?这可以提供哪些信息? - EdChum
2
你能计算出哪些圆将被其他圆完全重叠并跳过绘制它们吗? - wflynny
你能否不使用“Circle”补丁,而是画一个散点图呢?我相信这样会更加节省内存。请注意,您可以向“s”参数提供大小列表,因此就我所知,“Circle”补丁中没有任何散点图无法实现的功能。 - iayork
你希望从中获得什么信息?我建议在开始绘图之前对其运行例如kmeans。 - miraculixx
@edChum,相对于我关心的分辨率,圆的位置和直径的变化足够大,使得某些地方的圆重叠(您会注意到它们是透明的),这非常有意义。如果没有聪明的方法来处理它们,我将不得不进行分组或去重,但我希望尽可能避免失真。 - Chris
@iayork 我似乎无法弄清楚如何传递散点图和显式区域大小(以获取我的显式直径)。 - Chris
2个回答

2
在一个图中绘制所有300万个圆似乎不是可行的方法。以下是一个仅包含1000个圆的示例(按照matt_s的示例): 1000 circles overlapped 相反,我建议将要绘制的圆的数量减少到一些合理的值,例如50或100。一种方法是在数据集上运行KMeans来通过坐标和直径对圆进行聚类。以下图表表示了100,000个随机圆的聚类作为示例。这应该很容易扩展到3百万个圆。
标记的尺寸表示直径(s,缩放以适合图表),颜色表示每个聚类中的圆的数量(c)。您的情况可能有所不同。 enter image description here 用于绘制第一个图表的代码(ipython)
%matplotlib inline
import pandas as pd
import numpy as np
n = 1000
circles = pd.DataFrame({'x': np.random.random(n), 'y': np.random.random(n), 'r': np.random.random(n)},)
circles.plot(kind='scatter', x='x', y='y', s=circles['r']*1000, c=circles.r * 10, facecolors='none')

绘制第二张图表的代码(IPython)

%matplotlib inline
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# parameters
n = 100000
n_clusters = 50
# dummy data
circles = pd.DataFrame({'x': np.random.random(n), 'y': np.random.random(n), 'r': np.random.random(n)})
# cluster using kmeans
km = KMeans(n_clusters=n_clusters, n_jobs=-2)
circles['cluster'] = pd.Series(km.fit_predict(circles.as_matrix()))
# bin by cluster
cluster_size = circles.groupby('cluster').cluster.count()
# plot, using #circles / per cluster as the od weight
clusters = km.cluster_centers_
fig = plt.figure()
ax = plt.scatter(x=clusters[:,0], y=clusters[:,1], # clusters x,y
                 c=cluster_size, #color
                 s=clusters[:,2] * 1000, #diameter, scaled
                 facecolors='none') # don't fill markers
plt.colorbar()
fig.suptitle('clusters by #circles, c/d = size')
plt.xlabel('x')
plt.ylabel('y')

1
你尝试过使用pandas散点图吗?
import pandas as pd
import random

n = 100000
df = pd.DataFrame({'x': np.random.random(n), 'y': np.random.random(n), 'r': np.random.random(n)})
df.plot(kind='scatter', x='x', y='y', s=df['r']*1000, facecolor='none')

我觉得我做不到... 我应该提到我希望这些圆是空心的(即环形) - Chris
你可以将facecolors设置为'none'。 - matt_s
那应该是 facecolor 单数形式的;) - matt_s
啊...散点图的另一个棘手问题似乎是无法绘制具有绝对直径的圆。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接