这里的关键是使用Collection.在您的情况下,您想要制作PatchCollection.
Matplotlib通过使用集合优化绘制许多类似的艺术家.它比单独绘制每一个要快得多.此外,该剧情不会包含数千名个人艺术家,只有一个系列.这加快了每次绘制绘图时需要对每个艺术家进行操作的许多其他杂项操作.
散射实际上比你当前的方法快得多,因为它会添加一个集合而不是单独的艺术家.但是,它还会绘制尺寸不在数据坐标中的标记.
为了解决这个问题,您可以使用与分散相同的方法,但手动创建集合.
举个例子:
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()
这对我来说非常顺利.只是为了证明圆圈在数据坐标中,请注意如果我们放大一个窄矩形会发生什么(注意:这假设绘图的方面设置为自动):
如果您真的专注于速度,可以使用EllipseCollection作为@tcaswell建议.
EllipseCollection只会生成一个路径,但会在绘制时缩放并将其转换为您指定的位置/大小.
缺点是虽然大小可以在数据坐标中,但是圆圈将始终是圆形,即使绘图的宽高比不是1.(即圆圈不会像上图中那样拉伸) .
它的优点是速度快.
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()
当我们放大与第二个数字类似的区域时,请注意差异.圆圈变大(大小在数据坐标中),但保持圆形而不是变长.它们不是“数据”空间中圆圈的准确表示.
为了对时差有所了解,现在是时候用三种方法中的每一种创建和绘制具有相同5000个圆圈的图形:
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