BÚSCAME EN: Last FM Filmaffinity Facebook Youtuve Blogger Twitter Feed Instagram
Puedes acceder a este blog mediante las direcciones www.ignacionario.com o ignacionario.blogspot.com. También puedes contactar a través de la dirección de correo electrónico contacto@ignacionario.com.

4 de julio de 2011

Android (VI): Creación de gráficas estadísticas con Android Plot

Android (VI): Creación de gráficas estadísticas con Android Plot


¡Dos meses después de publicar el último tutorial vuelvo a la carga con un nuevo capítulo de esta emocionante aventura de ayudas para programar en Android! Desde que publiqué mi aplicación Train Yourself en el market de Android - enlace al market - , hace casi un mes (y hoy precisamente puedo decir muy contento que he superado las 1000 descargas) me han preguntado ya varias personas sobre cómo hice las gráficas estadísticas en la aplicación y todas ellas les dirigí a una página bastante completa y a la vez sencilla: Android Plot, y ahora intentaré hacer un breve resumen sobre cómo se usan.


Con Android Plot en concreto puedes realizar montones de gráficas distintas, pero aquí sólo me encargaré de indicaros brevemente cómo utilizarla para hacer tareas simples, ya que yo personalmente no he necesitado nada más.


1. Instalación de la librería en el proyecto
Una vez descargadas las librerías, debemos incluirlas en la carpeta LIB del proyecto, que es la que contiene las librerías externas al SDK de Android. Si la carpeta no existe podemos crearla sin ningún problema. Una vez añadidos los archivos, refrescamos la carpeta raíz del proyecto para que sean visibles desde Eclipse, y entonces debemos indicar que dichos archivos son librerías que deben usarse con el proyecto: Hacemos clic derecho a cada una de ellas y las importamos tal y como se muestra en la imagen.

Android (VI): Agregando las librerías al proyecto en Eclipse

2. Incluir el elemento (view) de la gráfica estadística en el layout en el que queremos mostrarla

Una vez añadida la librería ya podemos hacer uso de sus elementos sin que no de fallos el compilador. El siguiente paso es añadir al layout que deseemos el elemento VIEW llamado com.androidplot.xy.XYPlot correspondiente a la gráfica, que será el que se mostrará en pantalla. Se pueden añadir junto a él otros elementos como botones o algún TextView que se usen a modo de título.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
 
    <com.androidplot.xy.XYPlot
    android:id="@+id/mySimpleXYPlot"
    android:layout_width="fill_parent"
    android:layout_height="100px"
    android:layout_marginTop="10px"
    android:layout_marginLeft="10px"
    android:layout_marginRight="10px"
    title="A Simple XYPlot Example"/>
</LinearLayout

3. Introducir los datos desde el Activity que usa el layout 
Por último, una vez añadida la gráfica a la vista de diseño sólo nos quedaría indicarle qué datos se quieren mostrar. El código que se muestra a continuación (copiado literalmente desde la página original y comentado en español) nos muestra cómo indicar a la gráfica qué datos tiene que mostrar.

package com.example;
 
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.series.XYSeries;
import com.androidplot.xy.*;
 
import java.text.DecimalFormat;
import java.util.Arrays;
 
public class MyActivity extends Activity
{
 
    private XYPlot mySimpleXYPlot;
 
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        // Inicializamos el objeto XYPlot búscandolo desde el layout:
        mySimpleXYPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
 
        // Creamos dos arrays de prueba. En el caso real debemos reemplazar
        // estos datos por los que realmente queremos mostrar
        Number[] series1Numbers = {1, 8, 5, 2, 7, 4};
        Number[] series2Numbers = {4, 6, 3, 8, 2, 10};
 
        // Añadimos Línea Número UNO:
        XYSeries series1 = new SimpleXYSeries(
                Arrays.asList(series1Numbers),  // Array de datos
                SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Sólo valores verticales
                "Series1"); // Nombre de la primera serie
 
        // Repetimos para la segunda serie
        XYSeries series2 = new SimpleXYSeries(Arrays.asList(series2Numbers
), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY"Series2");
 
        // Modificamos los colores de la primera serie
        LineAndPointFormatter series1Format = new LineAndPointFormatter(
                Color.rgb(0, 200, 0),                   // Color de la línea
                Color.rgb(0, 100, 0),                   // Color del punto
                Color.rgb(150, 190, 150));              // Relleno
 
        // Una vez definida la serie (datos y estilo), la añadimos al panel
        mySimpleXYPlot.addSeries(series1, series1Format);
 
        // Repetimos para la segunda serie
        mySimpleXYPlot.addSeries(series2, new LineAndPointFormatter
(Color.rgb(0, 0, 200), Color.rgb(0, 0, 100), Color.rgb(150, 150, 190)));
 
    }
}
Una vez terminado de añadir todo el código, sólo nos queda ejecutar nuestra aplicación y comprobar el resultado.

Android (VI): Resultado visible de la gráfica estadística


43 comentarios:

  1. no tengo ni idea de lo que has puesto, pero te doy las gracias en nombre de alguien a quien le resulte útil y no comente :D

    ResponderEliminar
  2. JAJAJAJA, qúe bueno el comentario, Javier. Me ha encantado :D, gracias!! ^^

    ResponderEliminar
  3. Excelente! sabes si existen otras opciones para incluir gráficos estadísticos en una app?

    ResponderEliminar
  4. Muy buenas Isabel!!

    Hay varias, incluso hay una librería de google para navegadores web que puedes usar si implementas una vista web en tu aplicación, pero requeriría conexión a internet por parte de los usuarios.

    Échale un vistazo a estos enlaces:

    http://code.google.com/p/droidcharts/
    http://androidplot.com/wiki/Home
    http://www.achartengine.org/
    También hay otra posibilidad para cuando son informes generados con datos en la nube que es con un webview y con las google chart api:
    http://code.google.com/intl/es/apis/chart/

    Gracias por pasarte por aquí :)

    ResponderEliminar
  5. Jajaja, excelente el primer comentario.

    Estoy igual, aun no se que hacer con las gráficas estadísticas pero tengo que utilizarlas para un proyecto reciente. Tu entrada es un muy buen primer contacto.

    Gracias y salu2 :)

    ResponderEliminar
  6. yo he estado checando esto de las graficas estos ultimos dias y pues quizas involucra algunas mas complejas cosas...pero ojala pueda servile a alguien

    ResponderEliminar
  7. Claro, las gráficas estadísitcas pueden complicarse todo lo que uno quiera, en función del detalle que se quiera mostrar y de la importancia que tenga esto en tu aplicación!!

    Gracias a todos por escribir!!

    ResponderEliminar
  8. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  9. Hola Ignacion, te tengo un par de tres preguntas:

    - Como se puede quitar/cambiar las leyendas de Range y Domain?

    - Como puedo modificar los valores de Range y Domain que aparecen en la grafica? (los valores de Range son geniales, pero no me sirven los del domain)

    - Como cambiar las leyendas?

    Ya vi los ejemplos de AndroidPlot (algunos marcan errores) sin embargo tu explicación es por mucho mejor y sencilla.

    Espero puedas responder a la brevedad no sin antes agradecer tu publicación :)

    Salu2 :D

    ------------------------------------------------

    Ese era mi comentario anterior, pero ya encontré la respuesta xD

    Aun así seria genial leer una publicación tuya que responda esas interrogantes :)

    Gracias!!!
    Salu2 :)

    ResponderEliminar
  10. Muy buenas Fabián!! Gracias por compartir por aquí tus dudas!! A priori yo sólo he necesitado hacer cambios con dos de las que indicas por aquí:

    Para cambiar las leyendas Range y Domain:
    m_GraficaEstadistica.setRangeLabel("Nombre Range"); m_GraficaEstadistica.setDomainLabel("Nombre domain");

    Simplemente le indicas el nombre o una cadena vacía para no indicar nada.

    Para quitar los valores de range o domain no sé exactamente donde se hace porque no lo he necesitado, si quieres puedes indicarlo en un comentario por si alguien tiene esa misma duda.

    Y para cambiar el valor de las leyendas, pues mismamente cambias los valores del ejemplo donde aparece "Series1" y "Series2" por el nombre de la leyenda que quieras.

    Un saludo Fabián!! :D

    ResponderEliminar
  11. Una consulta, es posible que se pueda alimentar en tiempo real data X e Y de una Base de Datos???

    ResponderEliminar
  12. Claro, eso es lo que hago yo. En el ejemplo aparecen datos de prueba.

    Simplemente tendrás que hacer previamente la consulta y cargar los datos leídos en vez de esos datos que están escritos directamente en código :=)

    ResponderEliminar
  13. Ey!! gracias! ha sido de gran ayuda! Tengo una preguntita. No entiendo bien como coge los datos en el constructor:
    SimpleXYSeries( Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series1");
    ¿cuales son las x y cuales las y?

    ResponderEliminar
  14. Muy buen post, solo que tengo una duda y me urge mucho, en el domain como puedo poner nombres, en lugar de los numeros que aparecen deseo poner nombres, por ejemplo los dias de la semana, Lunes Martes... etc, espero me puedas ayudar lo mas pronto posible
    te dejo mi correo astaroth_1222@hotmail.com
    espero me contestes muy pronto

    ResponderEliminar
  15. Para los dos anónimos! :P

    Sobre el contructor, creo que ese es un constructor que sólo recibe valores Y, los X se crean automáticamente según la cantidad de numeros que se le pasa. Es decir, si se le pasa una lista de 5 valores pues las equis serían desde el 0 hasta el 4, seguro que hay otros tipos de constructores con posibilidad de pasar valores X.
    El propio constructor lo dice: ArrayFormat.Y_VALS_ONLY

    Sobre el último comentario, al segundo anónimo, pues ahora mismo no puedo ayudarte porque nunca he necesitado hacer eso y no tengo aquí el entorno de desarrollo, lo siento.

    Gracias a todos por escribir!

    ResponderEliminar
  16. Hola que tal soy el segundo Anonimo jeje, como sea gracias por tu aportacion apenas empeze a trabajar con ello y pues es lo unico que me falta cambiar esos valores, por lo demas ya no tengo ningun problema, gracias por compartir el conocimiento

    CasOR

    ResponderEliminar
  17. ignacio me parece super bueno el post. me gustaria saber como hago para
    graficar el consumo de mi procesador?

    ResponderEliminar
  18. Holaaa mi nombre es renata y estoy intentando entender el tema de gráficos... sería mucho pedir que hicieras un pequeño ejemplo con String. tipo enero febrero marzo y distintas cantidades... es que no llego a entender en su totalidad como va... porfiiisss... gracias

    ResponderEliminar
  19. q onda me gustaria poder ingresar los valores pero desde un EditText como le podria hacer

    ResponderEliminar
  20. Hola... Excelente ejemplo.. pero tengo una duda.. si quisiera hacerlo con datos que se encuentren en una base de datos como hago para mostrarlos desde la base de datos? podrias darme un ejemplo por favor... :D 

    ResponderEliminar
  21. Buenas Ignacio, curiosamente estoy realizando una aplicacion para gestionar entrenamientos, y mientras me documentaba sobre el tema de las graficas y demas, he dado con este fantastico tutorial sobre la libreria de AndroidPlot, cual ha sido mi sorpresa al ver que tu eres el desarrollador de TrainYour self, considero que es de los pocos programas sobre el tema en español que valen algo.

    Me gusto el tema de otorgar puntos, y las "pantallas de motivacion" despues de cada ejercicio, y toda la parte de Logeo de la actividad esta muy bien organizada.

    Por otro lado, se hecha un poco en falta un entorno un poco mas visual e interactivo a la hora de hacer los ejercicios, que curiosamente es en la parte en la que mas estoy incidiendo en mi proyecto.

    Mi enhorabuena por el proyecto.

    ResponderEliminar
  22. Una preguntas, has tenido que pagar algo por utilizar las librerias? tienen algun tipo de limitacion ?

    Gracias!!.

    ResponderEliminar
  23.  Usando la BD SQLite que trae android , normalmente cuando lanzas un select contra la base de datos , guardas los datos de  la consulta en un objeto de tipo Cursor, que posterior mente pueder recorrer para ir alimentando las estadisticas, seria algo asi:
    public void CargaDatos(){
         
        Cursor datos= null;
        String Estadistica1;
        int Estadistica2; 
     
        SQLiteDatabase getDatos = DB.getReadableDatabase();
           
            if(getDatos!=null){
                datos = getDatos.rawQuery("SELECT * FROM Tabla" ,null);
            }
            if(!datos.moveToFirst()){
                do{
                   //Codigo para alimentar las estadisticas
                     Estadistica1=datos.getString(numeroColumna);
                     Estadistica2= datos.getInt(numeroColumna);
            
                    }while(datos.moveToNext)
                }
                getDatos.close();
            }

    ResponderEliminar
  24. Hola que tal!

    Estoy desarrollando una aplicación y quiero mostrar ciertos datos en forma de gráfica. He probado el ejemplo de este foro y funciona a la perfección siempre y cuando el código de la graficación de los datos se coloque en el metodo onCreate, pero si dicho código lo coloco dentro de una función asociada a un botón para que cuando lo presione grafique simplemente no grafica los puntos. Alguna idea? De antemano gracias.
    El codigo de la funcion es:

    public void mostrarGraficas(View view)    {         // Inicializamos el objeto XYPlot búscandolo desde el layout:        mySimpleXYPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot);        mySimpleXYPlot2 = (XYPlot) findViewById(R.id.mySimpleXYPlot2);              // Creamos dos arrays de prueba. En el caso real debemos reemplazar        // estos datos por los que realmente queremos mostrar        Number[] series1Numbers = {1, 8, 5, 2, 7, 4};        Number[] series2Numbers = {4, 6, 3, 8, 2, 10};          // Añadimos Línea Número UNO:        XYSeries series1 = new SimpleXYSeries(                Arrays.asList(series1Numbers),  // Array de datos                SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Sólo valores verticales                "Distancia"); // Nombre de la primera serie          // Repetimos para la segunda serie        XYSeries series2 = new SimpleXYSeries(Arrays.asList(series2Numbers ), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");          // Modificamos los colores de la primera serie        LineAndPointFormatter series1Format = new LineAndPointFormatter(                Color.rgb(0, 200, 0),                   // Color de la línea                Color.rgb(0, 100, 0),                   // Color del punto                Color.rgb(150, 190, 150));              // Relleno          // Una vez definida la serie (datos y estilo), la añadimos al panel        mySimpleXYPlot.addSeries(series1, series1Format);                mySimpleXYPlot2.addSeries(series1, series1Format);                // Repetimos para la segunda serie        mySimpleXYPlot.addSeries(series2, new LineAndPointFormatter(Color.rgb(0, 0, 200), Color.rgb(0, 0, 100), Color.rgb(150, 150, 190)));                        mySimpleXYPlot.refreshDrawableState();                mySimpleXYPlot.refreshDrawableState();        }

    ResponderEliminar
  25. Hola Herras estoy enlazando una base SQLite con Androidplot pero no consigo podrías explicar un poco mas.

    un saludo

    ResponderEliminar
  26. El ejemplo que puse es bastante descriptivo:

    Conectas con la BD, lanzas la consulta, obtienes un objeto de tipo cursor que puedes recorrer para atacar las filas y campos que te devuelve la consulta.

    Estos datos puedes almacenarlos en un array o en un objeto de tipo List, una vez tienes los datos que necesitas almacenados ya puedes entregarselos al androplot, consulta la libreria para ver cual es la forma en que androplot consume los datos.

    ResponderEliminar
  27. aun no he podido colocar la gráfica modo horizontal (landscape) se puede 1 código para ambas pantalla?

    ResponderEliminar
  28. Oye una pregunta mira q intento agregarle valores float producto de una conversion que hize de un String a float y no me lee los datos la grafica sabes q puede ser ??

    ResponderEliminar
  29. Buenos dias tengo una duda alguien sabe como hacer una grafica del tipo Pentagonal? http://i255.photobucket.com/albums/hh152/AzuLoNe/eriror.gif de esta manera estoy buscando referencias pero son muy escasas si tienen algo por favor se los agradezco

    ResponderEliminar
  30. Como hiciste para cambiar lo de Domain y range y la leyenda?

    ResponderEliminar
  31. Excelente hermano! justo lo que estaba buscando. Se te agradece ! :D

    ResponderEliminar
  32. que tipo de datos son los que tengo que poner en series1Numbers y como se hace el casting... pues tengo unos numeros en string y los necesito graficar.
    griacias!

    ResponderEliminar
  33. Te agradezco infinitamente tu buena voluntad de compartir lo que haz aprendido, gracias a esta informacion pude realizar una aplicacion que si bien es muy sencilla, gracias a la Grafica que le agregué la hizo muy llamativa y me ayudo a obtener un buen punteo en un proyecto de la Universidad, lo unico engorroso es que ese boton de "Actualizar" solo actualiza los datos de arriba, la grafica solo cambia si muevo el dispositivo para que la orientacion cambie. La verdad no se porque, creo que debere leer mas sobre la libreria, Nuevamente Gracias, Saludos desde Guatemala

    ResponderEliminar
  34. Excelente!! muchas gracias por el tutorial saludos!!!

    ResponderEliminar
  35. Hola. Como podria guardar la grafica, por mas que lo he intentado no he podido. Saludos.

    ResponderEliminar
  36. Muchas gracias por el tutorial

    ResponderEliminar
  37. Como graficar datos sin utilizar el tipo de dato "Number",
    se puede enviar simples arreglos 'int' ? para graficar ??

    ResponderEliminar
  38. como puedo hacer para que la gráfica valla leyendo los datos introducidos por un arduino?

    ResponderEliminar
  39. Muchas gracias. Batallé un poco con:

    mySimpleXYPlot.addSeries(series2, new LineAndPointFormatter
    (Color.rgb(0, 0, 200), Color.rgb(0, 0, 100), Color.rgb(150, 150, 190)));

    Pero al leer la documentación que dejaste lo resolví así:

    mySimpleXYPlot.addSeries(series1, new LineAndPointFormatter
    (Color.rgb(0, 79, 136), // Color de la línea
    Color.rgb(14, 0, 135), // Color del punto
    Color.TRANSPARENT, // Relleno
    new PointLabelFormatter()));



    Muchas gracias, excelente tutorial =D

    ResponderEliminar
  40. Muchas gracias a Ignacio por el magnifico tutorial, y a tí Felipe por la solución tan facil que has encontrado para el PointFormatter.

    ResponderEliminar
  41. Ahora lo que no sé cono hacer es quitar los números que aparecen en los puntos de referencia si tienen idea me dicen por favor jeje

    ResponderEliminar
  42. Como se añade la librería en AndroidStudio

    ResponderEliminar
  43. como hago para meter en un objeto xyplot unos valores XY y que tengan forma de barras verticales?

    ResponderEliminar

Si estás conectado a tu cuenta de Google, puedes pulsar la opción Suscripción por correo electrónico que aparece a la derecha del botón Publicar comentario para recibir los comentarios que se publiquen en tu cuenta de correo electrónico, así podrás realizar un seguimiento de lo que se habla en esta entrada.
Si quieres enterarde de nuevos post, puedes subscribirte por correo, o hacerte seguidor tanto en blogger como en mi cuenta de twitter (ignacionario)

Related Posts Plugin for WordPress, Blogger...