Tengo alrededor de 50 000 columnas que quiero trazar en la misma figura. Aquí está el código que utilizo:
# "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)
Esto requiere un poco de tiempo (tengo que esperar unos 15 minutos). ¿Alguna sugerencia para optimizar el proceso / reducir el tiempo?
¡Gracias!
Una oración de respuesta: Use un LineCollection
.
Hay varias opciones para dibujar muchas líneas.
Uno puede recorrer los datos y crear una plot
por línea.
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)
En lugar de llamar a la plot
varias veces, se puede suministrar una matriz para plot
donde cada columna contiene los valores de una línea. Sin embargo, esto todavía creará tantos objetos Line2D
como columnas en la matriz.
def matrix(N, show=False): x = np.random.rand(N,3) y = np.random.rand(N,3) fig, ax = plt.subplots() ax.plot(xT, yT) if show: plt.show() else: fig.canvas.draw() plt.close(fig)
LineCollection
Una colección permite crear un solo artista, que se representa solo una vez. Esta es la opción más rápida.
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)
Se interceptará una línea en las posiciones de los valores de nan
en los datos. Esto permite trazar un solo Line2D
, pero con nan
s al final de cada bloque de datos que forma una línea individual.
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)
La ejecución de esas funciones para diferentes valores de N
a %timeit
da %timeit
resultado el siguiente gráfico.
Vemos que el LineCollection
lleva la menor cantidad de tiempo. Para grandes N
las diferencias son significativas. El bucle es el menos eficiente, seguido por la matriz. Esto se debe a que ambos crean N
líneas individuales que deben dibujarse. La línea única con nans y LineCollection son mucho más eficientes, con LineCollection
aún superando la plot
.