G A C E T A   D E   L I N U X
...haciendo a Linux un poco más divertido!
Explorando los módulos de Perl - Parte 2: Creando gráficas con GD::Graph
Por Pradeep Padala
Traducción al español por Javier Ballesteros
el día 18 de Marzo 2003, para La Gaceta de Linux

Introducción

Si leyó mi anterior artículo sobre GD, podría haber observado que crear gráficos con el módulo GD es incómodo. (Ese artículo también contiene alguna información general acerca de cargar módulos de Perl.) Martie Verbruggen ha creado el módulo GD::Graph que permite la sencilla creación de gráficos. Este módulo contiene funciones útiles para crear varios tipos de gráficos, como por ejemplo gráficos de barras, gráficos de sectores, gráficos de líneas, etc... El módulo es muy útil en la creación de gráficos dinámicos que representan estadísticas de red, estadísticas de accesos a páginas web, etc...

En este artículo, Describiré una forma general de usar el módulo y también se mostrarán algunos ejemplos de creación de distintos gráficos.

Uso típico del módulo GD::Graph

Un script en perl que usa GD::Graph para crear gráficos, típicamente contiene las siguientes cosas:

Un ejemplo sencillo

Dibujemos un gráfico sencillo siguiendo los pasos anteriores. Este script usa el módulo CGI para sacar la imagen a una página web.
[Versión texto de este listado.]

#!/usr/local/bin/perl -w
# Cambie la línea de arriba para que apunte a su binario de Perl

use CGI ':standard';
use GD::Graph::bars;
use strict;

# Ambos arrays deberían de tener el mismo número de entradas.
my @data = (["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
             "Sep", "Oct", "Nov", "Dec"],
            [23, 5, 2, 20, 11, 33, 7, 31, 77, 18, 65, 52]);

my $mygraph = GD::Graph::bars->new(500, 300);
$mygraph->set(
    x_label     => 'Month',
    y_label     => 'Number of Hits',
    title       => 'Number of Hits in Each Month in 2002',
) or warn $mygraph->error;

my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

print "Content-type: image/png\n\n";
print $myimage->png;

La salida del programa se puede ver aquí

El programa anterior es bastante autoexplicativo. La variable @data es una array de arrays. El primer array representa las etiquetas en el eje de las x's y el resto de arrays presentan los distintos conjuntos de datos.

Afinando las opciones

Como puede observar, el gráfico que produce el programa anterior es bastante suave y sencillo. Podemos ajustar varias opciones para producir un mejor aspecto y ajustar los gráficos. Hay multitud de opciones para controlar los distintos aspectos del gráfico. Las opciones se dividen en dos tipos: las opciones comunes a todos los tipos de gráficos y las opciones específicas a cada tipo de gráfico.

Las opciones se pueden establecer cuando se crea el gráfico o con

    $mygraph->set(attrib1 => value1, attrib2 => value2, ...);

Escribamos un script para poner los títulos de las leyendas, una rejilla y unas pocas opciones.
[Versión texto de este listado.]

#!/usr/local/bin/perl -w
# Cambie la línea de arriba para que apunte a su binario de Perl

use CGI ':standard';
use GD::Graph::bars;
use strict;

# Ambos arrays deberían de tener el mismo número de entradas.
my @data = (['Fall 01', 'Spr 01', 'Fall 02', 'Spr 02' ],
            [80, 90, 85, 75],
            [76, 55, 75, 95],
            [66, 58, 92, 83]);

my $mygraph = GD::Graph::bars->new(500, 300);
$mygraph->set(
    x_label     => 'Semester',
    y_label     => 'Marks',
    title       => 'Grade report for a student',
    # Dibuja barras con una anchura de 3 pixels
    bar_width   => 3,
    # Separa las barras con 4 pixels
    bar_spacing => 4,
    # Muestra la rejilla
    long_ticks  => 1,
    # Muestra los valores en lo alto de la barra
    show_values => 1,
) or warn $mygraph->error;

$mygraph->set_legend_font(GD::gdMediumBoldFont);
$mygraph->set_legend('Exam 1', 'Exam 2', 'Exam 3');
my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

print "Content-type: image/png\n\n";
print $myimage->png;

La salida del programa se puede ver aquí

Gráfico con un logo de fondo

Como puede ver, de nuevo, GD::Graph provee una forma sencilla de crear gráficos a la medida. Preparemos otro gráfico con un logo.

Versión texto de este listado aquí
#!/usr/local/bin/perl -w
# Cambie la línea de arriba para que apunte a su binario de Perl


use CGI ':standard';
use lib '/cise/homes/ppadala/mydepot/lib/perl5/site_perl';
use GD::Graph::bars;
use strict;

# Ambos arrays deberían de tener el mismo número de entradas.
my @data = (['Fall 01', 'Spr 01', 'Fall 02', 'Spr 02' ],
            [80, 90, 85, 75],
            [76, 55, 75, 95],
            [66, 58, 92, 83]);

my $mygraph = GD::Graph::bars->new(500, 300);
$mygraph->set(
    x_label     => 'Semester',
    y_label     => 'Marks',
    title       => 'Grade report for a student',
    # Dibuja barras con una anchura de 3 pixels
    bar_width   => 3,
    # Separa las barras 4 pixels
    bar_spacing => 4,
    # Muestra la rejilla
    long_ticks  => 1,
    # Muestra los valores el lo alto de cada barra
    show_values => 1,
) or warn $mygraph->error;

$mygraph->set(logo => 'lglogo.png');
$mygraph->set(logo_resize => 0.5);
$mygraph->set(logo_position => 'LL');
$mygraph->set_legend_font(GD::gdMediumBoldFont);
$mygraph->set_legend('Exam 1', 'Exam 2', 'Exam 3');
my $myimage = $mygraph->plot(\@data) or die $mygraph->error;
print "Content-type: image/png\n\n";
print $myimage->png;

La salida del programa se puede ver aquí

Aquí está el logo de Linux Gazette que he usado. Está en formato PNG. La versión actual de GD::Graph no reconoce cualquier tipo de imagen aparte de GIF (aunque lo puede escribir en PNG, vea la figura). Mandé un parche para arreglar esto. Puede, tanto aplicar el parche como usar una versión anterior de GD o GD::Graph.

gráficos con líneas

Alguna información se representa mejor usando gráficos de líneas. Aquí hay un ejemplo mostrando un gráfico de líneas.
[Versión texto de este listado.]

#!/usr/local/bin/perl -w
# Cambie la línea de arriba para que apunte a su binario de Perl

use CGI ':standard';
use GD::Graph::lines;
use strict;

# Ambos arrays deberían de tener el mismo número de entradas.
my @data = (['Fall 01', 'Spr 01', 'Fall 02', 'Spr 02' ],
            [80, 90, 85, 75],
            [76, 55, 75, 95],
            [66, 58, 92, 83]);

my $mygraph = GD::Graph::lines->new(600, 300);
$mygraph->set(
    x_label     => 'Semester',
    y_label     => 'Marks',
    title       => 'Grade report for a student',
    # Dibuja los datos en 'sólido', 'líneas' y 'semilíneas'
    line_types  => [1, 2, 4],
    # Pone la anchura de la línea
    line_width  => 2,
    # Pone los colores de los datos
    dclrs       => ['blue', 'green', 'cyan'],
) or warn $mygraph->error;

$mygraph->set_legend_font(GD::gdMediumBoldFont);
$mygraph->set_legend('Exam 1', 'Exam 2', 'Exam 3');
my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

print "Content-type: image/png\n\n";
print $myimage->png;

La salida del programa anterior se puede ver aquí

Aquí he usado GD::Graphic::lines para crear el descriptor del gráfico. Pero para cambiar esto, el programa sigue el mismo patrón que para crear gráficos.

Un gráfico de sectores

De forma parecida, podemos crear gráficos de sectores.
[Versión texto de este listado.]

#!/usr/local/bin/perl -w
# Cambie la línea de arriba para que apunte a su binario de Perl

use CGI ':standard';
use GD::Graph::pie;
use strict;

# Ambos arrays deberían de tener el mismo número de entradas.
my @data = (['Project', 'HW1', 'HW2', 'HW3', 'MidTerm', 'Final'],
            [25, 6, 7, 2, 25, 35]);

my $mygraph = GD::Graph::pie->new(300, 300);
$mygraph->set(
    title       => 'Grading Policy for COP5555 course',
    '3d'          => 1,
) or warn $mygraph->error;

$mygraph->set_value_font(GD::gdMediumBoldFont);
my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

print "Content-type: image/png\n\n";
print $myimage->png;

La salida del programa se puede ver aquí

La opción '3d' dibuja un gráfico de sectores en 3d.

Un gráfico de área

Un gráfico de área muestra los datos como un área bajo una línea.
[Versión texto de este listado.]

#!/usr/local/bin/perl -w
# Cambie la línea de arriba para que apunte a su binario de Perl

use CGI ':standard';
use GD::Graph::area;
use strict;

# Ambos arrays deberían de tener el mismo número de entradas.
my @data = (["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
             "Sep", "Oct", "Nov", "Dec"],
            [23, 5, 2, 20, 11, 33, 7, 31, 77, 18, 65, 52]);

my $mygraph = GD::Graph::area->new(500, 300);
$mygraph->set(
    x_label     => 'Month',
    y_label     => 'Number of Hits',
    title       => 'Number of Hits in Each Month in 2002',
) or warn $mygraph->error;

my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

print "Content-type: image/png\n\n";
print $myimage->png;

La salida del programa anterior se puede ver aquí

Conclusión

El módulo GD::Graph provee un forma sencilla y potente de crear gráficos. Es muy útil para la creación de gráficos dinámicos para servirlos vía web.

Espero que haya disfrutado leyendo este artículo. El próximo mes, le echaremos un vistazo al módulo PerlMagic.


Copyright © 2002, Pradeep Padala. Licencia de copia http://www.linuxgazette.com/copying.html
Publicado en el número 83 de Linux Gazette, Octubre 2002