如何快速绘制数千个圆圈? [英] How can I plot many thousands of circles quickly?

查看:68
本文介绍了如何快速绘制数千个圆圈?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试绘制几个(数千个)圆形对象 - 我没有太多使用 Python 的经验.我对指定位置、半径和颜色很感兴趣.有没有更有效的方法来达到相同的结果?:

I'm trying to plot several (many thousands) of circle objects - I don't have much experience working with python. I'm interested in specifying the position, radius and color. Is there a more efficient way to achieve the same result?:

import matplotlib.pyplot as plt

xvals = [0,.1,.2,.3]
yvals = [0,.1,.2,.3]
rvals = [0,.1,.1,.1]

c1vals = [0,.1,0..1]
c2vals = [.1,0,.1,0]
c3vals = [.1,.1,.1,.1]

for q in range(0,4):
    circle1=plt.Circle((xvals[q], yvals[q]), rvals[q], color=[0,0,0])
    plt.gcf().gca().add_artist(circle1)

推荐答案

此处的关键是使用 Collection .在您的情况下,您想要制作一个 PatchCollection.

The key here is to use a Collection. In your case, you want to make a PatchCollection.

Matplotlib 通过使用集合优化绘制许多相似的艺术家.这比单独绘制每个要快得多.此外,该地块将不包含成千上万的艺术家,仅包含一个收藏.这加快了每次绘制绘图时需要对每个艺术家进行的许多其他杂项操作.

Matplotlib optimizes drawing many similar artists through using collections. It's considerably faster than drawing each one individually. Furthermore, the plot won't contain thousands of individual artists, only one collection. This speeds up many other miscellaneous operations that need to operate on each artist every time the plot is drawn.

scatter 比您当前的方法快 ,因为它将添加一个收藏而不是单独的艺术家.但是,它还会绘制尺寸不在数据坐标中的标记.

scatter actually is much faster than your current approach, as it will add a collection instead of separate artists. However, it also draws markers with a size that isn't in data coordinates.

要解决此问题,您可以使用与 scatter 相同的方法,但要手动创建集合.

To get around that, you can use the same approach scatter does, but create the collection manually.

例如:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections

num = 5000
sizes = 0.2 * np.random.random(num)
xy = 50 * np.random.random((num, 2))

# Note that the patches won't be added to the axes, instead a collection will
patches = [plt.Circle(center, size) for center, size in zip(xy, sizes)]

fig, ax = plt.subplots()

coll = matplotlib.collections.PatchCollection(patches, facecolors='black')
ax.add_collection(coll)

ax.margins(0.01)
plt.show()

这对我来说非常流畅.只是为了证明圆圈在数据坐标中,注意如果我们放大一个狭窄的矩形会发生什么(注意:这假设绘图的方面设置为 auto):

This renders quite smoothly for me. Just to prove that the circles are in data coordinates, note what happens if we zoom in on a narrow rectangle (note: this assumes that the aspect of the plot is set to auto):

如果您真正专注于速度,可以按照@tcaswell的建议使用 EllipseCollection .

If you're really focused on speed, you can use an EllipseCollection as @tcaswell suggested.

EllipseCollection 只会制作一个路径,但会在绘制时将其缩放和转换为您指定的位置/大小.

An EllipseCollection will only make one path, but will scale and translate it at draw time to be in the places/sizes you specify.

缺点是虽然大小可以在数据坐标中,但圆圈始终是一个圆圈,即使绘图的纵横比不是 1.(即圆圈不会像在上图).

The downside is that while the size can be in data coordinates, the circle will always be a circle, even if the aspect ratio of the plot isn't 1. (i.e. the circles won't stretch as they do in the figure above).

优点是速度快.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections

num = 5000
sizes = 0.4 * np.random.random(num)
xy = 50 * np.random.random((num, 2))

fig, ax = plt.subplots()

coll = matplotlib.collections.EllipseCollection(sizes, sizes,
                                                np.zeros_like(sizes),
                                                offsets=xy, units='x',
                                                transOffset=ax.transData,
                                                **kwargs)
ax.add_collection(coll)
ax.margins(0.01)
plt.show()

当我们放大与第二个图相似的区域时,请注意差异.圆圈变大(大小在数据坐标中),但保持圆圈而不是变长.它们不是数据"空间中圆的准确表示.

Notice the difference as we zoom in on a similar region to the second figure. The circles get bigger (the size is in data coordinates), but remain circles instead of becoming elongated. They're not an accurate representation of a circle in "data" space.

为了了解时差,下面是使用三种方法中的每一种创建和绘制具有相同 5000 个圆的图形的时间:

To give some idea of the time difference, here's the time to create and draw a figure with the same 5000 circles with each of the three methods:

In [5]: %timeit time_plotting(circles)
1 loops, best of 3: 3.84 s per loop

In [6]: %timeit time_plotting(patch_collection)
1 loops, best of 3: 1.37 s per loop

In [7]: %timeit time_plotting(ellipse_collection)
1 loops, best of 3: 228 ms per loop

这篇关于如何快速绘制数千个圆圈?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆