2012-01-16 13 views
7

Estoy tratando de imprimir un gráfico de 600 ppp usando matplotlib de Python. Sin embargo Python trazada 2 de 8 gráficos, y la salida del error:Matplotlib Agg Error Complejidad de representación

OverflowError: Agg rendering complexity exceeded. Consider downsampling or decimating your data. 

estoy tramando una gran parte de los datos (7.500.000 datos por columna) así que supongo que ya sea que haya algún problema sobrecarga o que necesito establecer un gran cell_block_limit.

Intenté buscar las soluciones para cambiar un cell_block_limit en Google, pero fue en vano. ¿Cuál sería un buen enfoque?

El código de la siguiente manera: -

 import matplotlib.pyplot as plt 
     from matplotlib.ticker import MultipleLocator, FormatStrFormatter 

     majorLocator = MultipleLocator(200) 
     majorFormatter = FormatStrFormatter('%d') 
     minorLocator = MultipleLocator(20) 

     fig = plt.figure() 
     ax = fig.add_subplot(111) 
     ax.xaxis.set_major_locator(majorLocator) 
     ax.xaxis.set_major_formatter(majorFormatter) 
     ax.xaxis.set_minor_locator(minorLocator) 
     ax.xaxis.set_ticks_position('bottom') 
     ax.xaxis.grid(True,which='minor') 
     ax.yaxis.grid(True) 
     plt.plot(timemat,fildata) 
     plt.xlabel(plotxlabel,fontsize=14) 
     plt.ylabel(plotylabel,fontsize=14)  
     plt.title(plottitle,fontsize=16) 
     fig.savefig(plotsavetitle,dpi=600) 
+0

es una gran cantidad de datos, teniendo en cuenta un 1600x1200 tendría 'sólo' 1.920.000 _pixels_ allí. ¿Qué tipo de trama estás tratando de hacer? Si se trata de un histograma, puede bin, una línea puede ser submuestreo .. – wim

+0

son datos del acelerómetro muestreados a 1500 Hz para capturar el choque de alta frecuencia. Estoy tratando de hacer la simple gráfica de Voltaje (V) vs Tiempo. Entonces primero genero la cantidad similar de datos para una matriz de tiempo, y grafico la señal contra el tiempo. Sí, es enorme, pero en el futuro estoy seguro de que será incluso enorme, ya que estamos haciendo un experimento de 2 horas a 4 horas. Por favor, dime cómo submuestrear una línea ... ¡muchas gracias! –

+1

usa un corte en las entradas (en ambos ejes). por ejemplo, para seleccionar cada décimo elemento de una matriz 'x' usaría' x [:: 10] ' – wim

Respuesta

15

Además del punto de @ Lennart de que no hay necesidad de la resolución completa, también podría considerar una trama similar a la siguiente.

Cálculo del máximo/media/min de un "fragmentada" versión es muy sencilla y eficaz si se utiliza una vista 2D de la serie original y la palabra clave axis arg a x.min(), x.max(), etc.

Incluso con el filtrado, trazar esto es mucho más rápido que trazar la matriz completa.

(Nota: para trazar estos puntos, tendrá que ajustar un poco el nivel de ruido. De lo contrario, obtendrá el OverflowError que mencionó. Si desea comparar el trazado del conjunto de datos "completo", cambie el y += 0.3 * y.max() np.random... línea a más como 0.1 o eliminarlo por completo.)

import matplotlib.pyplot as plt 
import numpy as np 
np.random.seed(1977) 

# Generate some very noisy but interesting data... 
num = 1e7 
x = np.linspace(0, 10, num) 
y = np.random.random(num) - 0.5 
y.cumsum(out=y) 
y += 0.3 * y.max() * np.random.random(num) 

fig, ax = plt.subplots() 

# Wrap the array into a 2D array of chunks, truncating the last chunk if 
# chunksize isn't an even divisor of the total size. 
# (This part won't use _any_ additional memory) 
chunksize = 10000 
numchunks = y.size // chunksize 
ychunks = y[:chunksize*numchunks].reshape((-1, chunksize)) 
xchunks = x[:chunksize*numchunks].reshape((-1, chunksize)) 

# Calculate the max, min, and means of chunksize-element chunks... 
max_env = ychunks.max(axis=1) 
min_env = ychunks.min(axis=1) 
ycenters = ychunks.mean(axis=1) 
xcenters = xchunks.mean(axis=1) 

# Now plot the bounds and the mean... 
ax.fill_between(xcenters, min_env, max_env, color='gray', 
       edgecolor='none', alpha=0.5) 
ax.plot(xcenters, ycenters) 

fig.savefig('temp.png', dpi=600) 

enter image description here

+1

¡EXCELENTE! ¡Una manera extremadamente informativa e innovadora de ver los datos! +++ –

3

Con 600dpi que tendría que hacer la parcela de 13 metros de ancho para trazar los datos sin diezmando él. :-)

Sugeriría fragmentar los datos en trozos de un par de cientos o quizás hasta mil muestras, y extraer el valor máximo de eso.

Algo como esto:

def chunkmax(data, chunk_size): 
    source = iter(data) 
    chunk = [] 
    while True: 
     for i in range(chunk_size): 
      chunk.append(next(source)) 

     yield max(chunk) 

Esto entonces, con un chunk_size de 1000 le dará 7500 puntos de trama, en la que a continuación, puede fácilmente ver donde en los datos de la cual el amortiguador. (A menos que los datos sean tan ruidosos, tendría que promediarlos para ver si hay o no choques, pero eso también es fácilmente reparable).

+0

gracias! Parece que realmente no hay otra manera de trazar un diagrama de alta dpi. –

+1

FYI: Si bien es una sugerencia excelente, el código actual es muy ineficiente para las matrices numpy. sería mejor hacer algo como 'chunks = data.reshape ((- 1, chunk_size)); max_filtered = chunks.max (axis = 1)'. (Suponiendo el caso simple donde el tamaño del fragmento es un divisor par del tamaño total ... Un ejemplo generalizado es solo una o dos líneas adicionales) –

+0

@JoeKington: ¿Ah, usa numpy? No lo entendí. ¿Realmente se está iterando sobre una matriz numpy? Oh, bueno. –