我有大约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分钟)。有什么优化流程/缩短时间的建议吗?
谢谢!

最佳答案

一句话回答:使用LineCollection
有几个选项可以绘制许多线。
A.环路
我们可以循环遍历数据并为每行创建一个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)

B.绘制矩阵
不必多次调用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)

C.ALineCollection
集合允许创建一个艺术家,该艺术家只呈现一次。这是最快的选择。
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,但在组成单个行的每个数据块的末尾都有nans。
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的不同值运行这些函数将得到下图。
python - 在更短的时间内完成许多绘图-Python-LMLPHP
我们看到LineCollection花费的时间最少。对于大的N来说,差异是显著的。循环的效率最低,其次是矩阵。这是因为两者都会创建需要绘制的单独线条。带有nans的单行线和行集合的效率更高,N仍优于LineCollection

关于python - 在更短的时间内完成许多绘图-Python,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54492963/

10-12 22:02