wolfram two tables mathematica lists listplot how color wolfram-mathematica plot

wolfram mathematica - two - Acelera ListLinePlot



plot options mathematica (4)

Estoy tratando de usar Mathematica para analizar algunos datos sin procesar. Me gustaría poder mostrar dinámicamente el rango de datos que me interesan usando Manipulate y ListLinePlot , pero la representación de la gráfica es extremadamente lenta. ¿Cómo puedo acelerarlo?

Aquí hay algunos detalles adicionales. Un archivo de texto externo almacena los datos sin procesar: la primera columna es una marca de tiempo, la segunda, tercera y cuarta columnas son lecturas de datos, por ejemplo:

1309555993069, -2.369941, 6.129157, 6.823794 1309555993122, -2.260978, 6.170018, 7.014479 1309555993183, -2.070293, 6.129157, 6.823794 1309555993242, -1.988571, 6.238119, 7.123442

Un solo archivo de datos contiene hasta 2 · 10 6 líneas. Para mostrar, por ejemplo, la segunda columna, utilizo:

x = Import["path/to/datafile"]; ListLinePlot[x[[All, {1, 2}]]]

El tiempo de ejecución de esta operación es insoportablemente largo. Para mostrar un rango variable de datos intenté usar Manipulate :

Manipulate[ListLinePlot[Take[x, numrows][[All, {1, 2}]]], {numrows, 1, Length[x]}]

Esta instrucción funciona, pero se arrastra rápidamente cuando intento mostrar más de unas mil líneas. ¿Cómo puedo acelerarlo?

Algunos detalles adicionales:

  • MATLAB muestra la misma cantidad de datos en la misma computadora de forma casi instantánea, por lo que el tamaño de los datos en bruto no debería ser un problema.
  • Ya traté de desactivar gráficos antialiasing, pero no afectó la velocidad de renderizado.
  • Usar DataRange para evitar Take no ayuda.
  • El uso de MaxPlotPoints distorsiona demasiado la trama para ser útil.
  • No usar Take in Manipulate no ayuda.
  • La renderización parece tomar mucho tiempo. Running Timing[ListLinePlot[Take[x,100000][[All, {1, 2}]]]] devuelve 0.33 : esto significa que la evaluación de Take por sí misma es casi instantánea, es la representación de la trama que ralentiza todo.
  • Estoy ejecutando Mathematica en Ubuntu Linux 11.10 usando los controladores fglrx. Obligar a Mathematica a usar controladores de mesa no ayudó.

¿Alguna pista?


También noté que, de vez en cuando, Mathematica tardará demasiado en representar gráficos. En realidad, debe ser un paso de traducción de una expresión de Graphics Mathematica a otra representación que lleva mucho tiempo porque una vez procesada, redimensionado (y por lo tanto re-renderizado) el gráfico es mucho más rápido. La representación gráfica previa a la versión 6 solía ser más rápida para muchos ejemplos (pero también carece de una gran cantidad de funcionalidades con más de 6).

Algunas ideas sobre lo que podrías hacer:

  1. Use la opción MaxPlotPoints de ListLinePlot para reducir los datos antes de trazar. Puede no hacer una diferencia en el aspecto si se muestrea de forma insuficiente. La opción Method debe elegir el algoritmo de reducción de resolución, pero no puedo encontrar ningún documento (¿alguien?)

  2. Use ContinuousAction -> False en Manipulate para evitar que vuelva a calcular todo en tiempo real a medida que arrastra los controles deslizantes.


No he probado mucho esto en mi máquina (tengo una Mac, por lo que no puedo descartar problemas específicos de Linux). pero un par de puntos se me ocurren. Lo siguiente fue bastante rápido para mí, pero obviamente más lento que si el conjunto de datos fuera más pequeño. Está tramando cientos de miles de puntos de datos.

data = Accumulate@RandomVariate[NormalDistribution[], 200000]; Manipulate[ListLinePlot[Take[data, n]], {n, 1, Length[data]}]

  1. En un Manipulate , está permitiendo que la cantidad de datos mostrada con Take varíe arbitrariamente. Intenta incrementar numrows cada 100 o más puntos, por lo que hay menos para renderizar.
  2. Intente utilizar la opción ContinuousAction->False (consulte la documentación ) (Veo que @Szabolcs tenía la misma idea que estaba escribiendo).
  3. Estaba a punto de sugerir MaxPlotPoints , pero en su lugar probé la opción PerformanceGoal ->"Speed" . (ver documentación )

Otra idea es usar el algoritmo Ramer-Douglas-Peucker para reducir el número de puntos de datos antes de trazar. Es probable que esto preserve la forma de los datos mejor. No sé si todavía necesita esto, así que no proporcionaré una implementación.


Si su objetivo es simplemente visualizar sus datos de manera rápida pero adecuada, puede usar el siguiente truco, que estoy usando constantemente.

Participo los datos en un número de bloques que corresponden aproximadamente a la resolución de mi pantalla (generalmente 1000 o menos), de todos modos no se pueden mostrar más detalles. Luego, determino el Mín. Y el Máx. De cada bloque y trazo una línea en zig-zag de mínimo a máximo a mínimo a máximo ... El resultado se verá exactamente como los datos originales. Sin embargo, no puede "acercarse", ya que entonces verá la línea zig-zag (por ejemplo, al exportar a alta resolución en pdf). Entonces necesitas usar una mayor cantidad de bloques.

rv = RandomVariate[ExponentialDistribution[2], 100000]; ListLinePlot[rv, PlotRange -> All] (* original, slow *) ListLinePlot[rv, PlotRange -> All, MaxPlotPoints -> 1000] (* fast but distorted *) numberOfBlocks = 1000; ListLinePlot[Riffle @@ Through[{Min /@ # &, Max /@ # &}[ Partition[rv,Floor[Length[rv]/numberOfBlocks]]]], PlotRange -> All]

Puede agregar la DataRange->{...} para etiquetar apropiadamente el eje x.

¡Espero que esto ayude!

EDITAR: Vea también esta pregunta similar en Mathematica Stackexchange: https://mathematica.stackexchange.com/q/140/58