【发布时间】:2015-01-03 10:17:09
【问题描述】:
我正在尝试绘制大量具有不同外观(形状、边缘颜色、面部、颜色等)的点,并且发现绘制明显的方式(对每个点使用 plot)需要非常很久。我看到了各种提高性能的方法,但发现这些方法要么降低了点外观的灵活性,要么最终变得比我认为正确的低得多。
例如,如果我有
fig, ax = matplotlib.pyplot.subplots()
rands = numpy.random.random_sample((n,))
其中n 是一个很大的数字,然后使用plot 绘制每个点
for x in range(n):
ax.plot(x, rands[x], 'o', color=str(rands[x]), mec=str(1-rands[x]))
需要很长时间,而且似乎效率很低。通过一次绘制多个点可以获得更快的结果
ax.plot(range(n), rands, 'o', color='b', mec='r')
但失去了对单个点的许多特征的控制(例如,color 和 mec 都不能是列表,许多其他方面也受到同样的限制)。使用像scatter这样的便捷方法
ax.scatter(range(n), rands, marker='o', color=[str(y) for y in rands])
也产生快速的结果;但同样失去了相当大的灵活性(尽管点可以单独着色,不支持plot 用于设置单个点的特征的剩余选项)和一些自动轴限制(使用set_xlim 和set_ylim 似乎必须完成 plot 自动执行的操作)。
最后,我看到许多示例将图形元素(如圆圈)与 collections 结合使用,虽然“对于常见用例来说速度很快”,但在我看来代码看起来“低级”
patches = []
colors = []
for x in range(n):
circ = matplotlib.patches.Circle((x/float(n), rands[x]), .01)
colors.append([rands[x],rands[x],rands[x]])
patches.append(circ)
collection = matplotlib.collections.PatchCollection(patches)
collection.set_facecolor(colors)
collection.set_edgecolor([[1-h for h in c] for c in colors])
ax.add_collection(collection)
因为它不仅打破了绘图点的抽象,而且还需要相当大的缩放和调整来恢复(甚至部分)由plot自动提供的外观(例如matplotlib.pyplot.axis('equal')是有必要避免扭曲的“点”)。
这很令人沮丧,因为plot 似乎是一种自然的使用方法,因为它提供了对各个点的所有正确自定义,并产生了很好的缩放比例和自然有界的轴 - 使用时太慢了一个时间点,并且不接受列表作为大多数属性的参数。
绘制大量点的正确 Pythonic 方法是什么,其中每个点的特征(标记、边缘颜色、面部颜色、alpha、大小等)必须可能进行自定义?使用圆形(或其他形状)和集合(然后对图形进行缩放和其他调整)真的是首选(或至少是必要的)方法吗?
【问题讨论】:
-
继前面的讨论stackoverflow.com/a/26764169/249341 之后,我认为自己编写一个自定义绘图函数once 来满足您的需要(例如,可变大小,等)并将其用于所有未来的项目。可以向 matplotlib 团队提交更多可定制性请求。这个网站上有几个活跃的开发者,也许他们会给你一些提示。
-
@Hooked:是的。但问题是,即使是这样的自定义函数是否也是 Pythonic 方式。并同意:很高兴看到
plot的点样式参数将列表作为参数。事实上,似乎必须放弃绘图并改用 绘图(如果属实,这似乎是一个严重的缺点)。
标签: python performance matplotlib plot