加速matplotlib散点图绘制

11
我正在尝试制作一个交互式程序,主要使用matplotlib制作相当多的点(大约10k-100k)。目前虽然可以工作,但更改渲染时间太长。小数量的点还好,但一旦数量增加,事情就会变得令人沮丧。因此,我正在寻找加速绘制散点图的方法,但运气不太好。 目前实现方式是很明显的方式(像现在这样实现)(我知道绘图重新绘制而不更新。我不想通过大量调用随机函数来改变fps结果)。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
import time


X = np.random.randn(10000)  #x pos
Y = np.random.randn(10000)  #y pos
C = np.random.random(10000) #will be color
S = (1+np.random.randn(10000)**2)*3 #size

#build the colors from a color map
colors = mpl.cm.jet(C)
#there are easier ways to do static alpha, but this allows 
#per point alpha later on.
colors[:,3] = 0.1

fig, ax = plt.subplots()

fig.show()
background = fig.canvas.copy_from_bbox(ax.bbox)

#this makes the base collection
coll = ax.scatter(X,Y,facecolor=colors, s=S, edgecolor='None',marker='D')

fig.canvas.draw()

sTime = time.time()
for i in range(10):
    print i
    #don't change anything, but redraw the plot
    ax.cla()
    coll = ax.scatter(X,Y,facecolor=colors, s=S, edgecolor='None',marker='D')
    fig.canvas.draw()
print '%2.1f FPS'%( (time.time()-sTime)/10 )

这将提供快速的0.7帧每秒。

或者,我可以编辑scatter返回的集合。对此,我可以更改颜色和位置,但不知道如何更改每个点的大小。我认为它看起来应该是这样的。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
import time


X = np.random.randn(10000)  #x pos
Y = np.random.randn(10000)  #y pos
C = np.random.random(10000) #will be color
S = (1+np.random.randn(10000)**2)*3 #size

#build the colors from a color map
colors = mpl.cm.jet(C)
#there are easier ways to do static alpha, but this allows 
#per point alpha later on.
colors[:,3] = 0.1

fig, ax = plt.subplots()

fig.show()
background = fig.canvas.copy_from_bbox(ax.bbox)

#this makes the base collection
coll = ax.scatter(X,Y,facecolor=colors, s=S, edgecolor='None', marker='D')

fig.canvas.draw()

sTime = time.time()
for i in range(10):
    print i
    #don't change anything, but redraw the plot
    coll.set_facecolors(colors)
    coll.set_offsets( np.array([X,Y]).T )
    #for starters lets not change anything!
    fig.canvas.restore_region(background)
    ax.draw_artist(coll)
    fig.canvas.blit(ax.bbox)
print '%2.1f FPS'%( (time.time()-sTime)/10 )

这导致速度变慢了0.7帧每秒。我想尝试使用CircleCollection或RegularPolygonCollection,因为这样可以轻松更改大小,而且我不关心更改标记。但是,我无法绘制任何一个,所以我不知道它们是否会更快。所以,在这一点上,我正在寻找想法。


你使用的是哪个版本? - tacaswell
1
请参见 https://github.com/matplotlib/matplotlib/pull/2156。 - tacaswell
Python版本2.7.3,matplotlib 1.2.0。 - george
2个回答

8
我曾多次尝试优化散点图的速度,包括:
- 使用不同的标记类型 - 限制颜色 - 减少数据集大小 - 使用热力图/网格而非散点图
但是这些方法均无效。Matplotlib在处理散点图时性能不佳。我的唯一建议是使用其他绘图库,但我个人还没有找到合适的库。虽然这并没有太多帮助,但可以避免您花费数小时进行徒劳的调试。

2
我真的希望那不是答案,matplotlib非常方便。你能否提及一些你尝试过但不适合的matplotlib替代品,这样我就不用浪费时间去发现它们行不通了?目前,我要尝试的首选是chaco。 - george
我只是尝试了几个,但我们最终还是选择了matplotlib,因为它是最方便和最受支持的。如果我需要像你的问题一样快速处理数据,我的下一个选择将是rpy2 - R专为大数据设计,人们会认为他们的图表相当迅速:http://rpy.sourceforge.net/rpy2/doc-2.2/html/graphics.html - John Lyon
我会推荐最后两种选择。如果你只是想要一个漂亮的可视化样本,没必要绘制整个图形。通常用子样本散点图就足够了。或者你也可以将样本分组,并显示一些粗粒度(根据需要进行平滑)的图像,改变每个组(或“像素”)中的值来匹配颜色/强度。这样可以保留 matplotlib,而不使它面对太大的问题。 - Cong Ma

7

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