2010-01-14 14 views
11

Tengo un conjunto de datos con 100 000 puntos de datos que debo trazar en un gráfico. El gráfico resultante tendrá aproximadamente 500 px de ancho, por lo que para cada píxel habrá cerca de 200 puntos de datos, lo que parece bastante innecesario.Reducir los datos del gráfico sin perder la forma del gráfico

Necesito encontrar una manera de deshacerme de los puntos de datos excedentes sin perder la forma del gráfico para acelerar el renderizado. Actualmente, la renderización de los 100 000 puntos puede tomar más de 10 segundos ya que también estoy usando anti-aliasing y otros "efectos".

Intenté abordar este problema tomando cada punto de datos número 200 y trazándolos, pero esto da como resultado la pérdida de algunos de los puntos más significativos (piense en los picos en el gráfico que deseo poder mostrar). También pensé en dividir el conjunto de datos en fragmentos de 200 puntos de datos, y luego tomar el valor máximo de cada fragmento pero eso tampoco funcionaría.

¿Alguien conoce un método que se adapte a mis necesidades aquí? El lenguaje que estoy usando es PHP, el gráfico es creado por GD y los datos provienen de MySQL, por lo que las optimizaciones para algunos de ellos son bienvenidas.


Los datos están en este formato:

Datetime    Value 
2005-01-30 00:00:00 35.30 
2005-01-30 01:00:00 35.65 
2005-01-30 02:00:00 36.15 
2005-01-30 03:00:00 35.95 
... 

Y la gráfica resultante Actualmente tiene este aspecto:

alt text http://www.ulmanen.fi/stuff/graph-sample.png

+1

¿Puede decir por qué no funciona el consumo máximo en cada contenedor de 200 puntos? ¿Qué hay de hacer el gráfico desplazable o con zoom (es decir, no mostrar todo de una vez)? Además, ¿los datos son estáticos, o más o menos estáticos, por lo que podría existir la posibilidad de preprocesarlos en la base de datos? –

+1

@martin clayton, porque también quiero tener en cuenta los picos 'min', usar max los destruiría. En esencia, necesito un método para encontrar el punto más significativo en un trozo de 200 puntos. –

+0

Si su resolución no puede mostrar los detalles de sus datos, entonces su resolución es demasiado pequeña. – Svante

Respuesta

9

Me parece que 1 en 200 es una pérdida de datos bastante grave, y si esos 200 valores que deben representarse con un valor en el gráfico no son lo suficientemente cercanos para ser sustituidos significativamente por un promedio, usted mismo problema. Si el promedio no es lo suficientemente bueno, debe encontrar un criterio para decir qué datos son más significativos y deben incluirse, y no podemos ayudarlo porque no sabemos qué tipo de datos son, sus propiedades estadísticas , o por qué cualquier valor sería más significativo que el otro. Con esa información adicional, tal vez se podría dar una respuesta más específica.

EDITAR: Después de mirar el gráfico, parece que necesita tanto el mínimo como el máximo en un intervalo dado, porque el área azul oscura son valores entre esos dos, ¿correcto? Tal vez pueda tomar 100 valores y hacer un gráfico de mínimo, máximo y promedio, de modo que cada punto del gráfico se haga con 6 en lugar de 200 valores, o algo así.

+0

Sí, también pensé en usar tanto min como max. Tal vez podría obtener un resultado similar al usar dos líneas y sombrear el entre medio, y tal vez una tercera línea para mostrar el valor promedio en la parte superior. Buenos puntos. A menos que a alguien se le ocurra una ecuación sólida sobre cómo hacer esto de la manera que originalmente pensé, voy a marcar este como aceptado. –

0

No sé cuál es su código/fuente de datos parece, pero ¿es posible hacer una distinción en su declaración de selección de MySQL para reducir la cantidad de puntos de datos que se regresan a su aplicación?

+0

Actualicé mi respuesta para incluir algunos datos de muestra. Usar DISTINCT no funcionará, ya que podría omitir los puntos más "importantes". –

+0

Veo lo que está mirando ahora, para cada píxel de ancho, cuántos puntos hay dentro y cómo se determina qué ancho de píxel contiene qué elementos. – mynameiscoffey

1

Creo que el promedio ordinario de cada 200 grupos de puntos sería suficiente.

+0

O como se señaló más alto, puede tomar un máximo de estos 200 puntos o cualquier otro que desee (depende de la información que necesita de este gráfico) – user204724

+1

Promedio ordinario no es suficiente si tengo 199 puntos con valor de 15 y 1 punto con valor de 1200. Quiero poder mostrar ese punto distintivo allí. –

2

Un enfoque para su problema es la destrucción máxima-mínima; Le sugiero que busque una definición y un algoritmo que no tengo a mano o que quisiera compartir con usted.

Más allá de eso, creo que podría utilizar un filtro de paso bajo (anti-aliasing) seguido de una simple destrucción (es decir, tirar el exceso de puntos).

2

Otro enfoque que podría funcionar es dividir el gráfico en contenedores de 200 puntos, y descartar todos los puntos, excepto el máximo, mínimo y mediano en cada intervalo. Cada uno de los tres puntos en el intervalo se traza en su ubicación original, por lo que las ubicaciones de los valores extremos no cambiarán.Usar la mediana en lugar de la media probablemente funcione mejor para su conjunto de datos porque los máximos son mucho más extremos que los mínimos, lo que causaría que el gráfico filtrado se moviera hacia arriba si usaba la media.

+0

Buenos puntos, gracias. –

13

Sé que esta pregunta es bastante antigua pero tuve un problema casi similar.

Para reducir el número de puntos para mostrar sin afectar la forma del gráfico, usamos el Ramer-Douglas-Peucker algoritm. La diferencia de forma entre el gráfico descomprimido y el que tiene este algoritmo es imperceptible.

Cuestiones relacionadas