我要在同一图中绘制约5万列。这是我使用的代码:
# "Xaxis" is a list containing the x-axis, and "data" a list of the 50 000 data series I want to plot.
for elt in data:
plt.plot(Xaxis,elt)
这有点耗时(我需要等待约15分钟)。有什么优化流程/减少时间的建议吗?
谢谢!
答案 0 :(得分:2)
一个句子的答案:使用LineCollection
。
有几种方法可以绘制多条线。
一个人可以遍历数据并每行创建一个plot
。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
def loop(N, show=False):
x = np.random.rand(N,3)
y = np.random.rand(N,3)
fig, ax = plt.subplots()
for i in range(N):
ax.plot(x[i], y[i])
if show:
plt.show()
else:
fig.canvas.draw()
plt.close(fig)
您可以代替向plot
多次调用,而可以向plot
提供一个矩阵,其中每一列都包含一行的值。但是,这仍将创建与矩阵中的列一样多的Line2D
对象。
def matrix(N, show=False):
x = np.random.rand(N,3)
y = np.random.rand(N,3)
fig, ax = plt.subplots()
ax.plot(x.T, y.T)
if show:
plt.show()
else:
fig.canvas.draw()
plt.close(fig)
LineCollection
一个集合允许创建一个艺术家,该艺术家只能渲染一次。这是最快的选择。
from matplotlib.collections import LineCollection
def linecoll(N, show=False):
x = np.random.rand(N,3)
y = np.random.rand(N,3)
data = np.stack((x,y), axis=2)
fig, ax = plt.subplots()
ax.add_collection(LineCollection(data))
if show:
plt.show()
else:
fig.canvas.draw()
plt.close(fig)
在数据中nan
值的位置将截取一行。这允许绘制单个Line2D
,但在组成单独行的每个数据块的末尾带有nan
。
def fillednan(N, show=False):
x = np.random.rand(N,3)
y = np.random.rand(N,3)
X = np.concatenate((x, np.ones_like(x)*np.nan)).flatten()
Y = np.concatenate((y, np.ones_like(x)*np.nan)).flatten()
fig, ax = plt.subplots()
ax.plot(X,Y)
if show:
plt.show()
else:
fig.canvas.draw()
plt.close(fig)
针对N
至%timeit
的不同值运行这些函数,结果如下图所示。
我们看到LineCollection
花费的时间最少。对于较大的N
,差异是很大的。循环效率最低,其次是矩阵。这是因为两者都创建了N
个别需要绘制的线。带有nans和LineCollection的单行效率更高,LineCollection
仍然胜过plot
。