Mastering Perl for Bioinformatics [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Mastering Perl for Bioinformatics [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










8.4 Making Graphs


Displaying data graphically (graphs,
bar graphs, pie charts, etc.) is the most common goal of image
programming You've just seen how the GD Perl module
helps you create graphics. It's great for quickly
providing images from CGI web programs.

GD::Graph, another Perl module that uses GD as its
underlying mechanism, does an excellent job of rendering all sorts of
graphs. Programming graphs with GD::Graph is
relatively easy, especially if you start with the example programs
and modify them for your own purposes. The module is object oriented,
and it provides many options for displaying the various graphs. Plan
to take some time exploring the documentation and trying different
options as you begin programming with GD::Graph.
Its flexible yet relatively simple programming interface has made it
a popular and powerful module. GD::Graph can be
found on CPAN. It's simple to install once you have
GD itself installed.

For more in-depth information on graphics programming in Perl, see
Perl Graphics Programming by Shawn Wallace
(O'Reilly). The book includes a chapter on
GD::Graph that can serve as a fine tutorial. The
documentation for GD::Graph (on CPAN, or type
perldoc GD::Graph in a terminal
window) is well-written and clearly organized. The software comes
with several example programs that will help get you started.

The following short program, gd1.pl, uses GD::Graph to
create a simple bar graph.

#!/usr/bin/perl
#
# gd1.pl -- create GD::Graph bar graph
#
use strict;
use warnings;
use Carp;
use GD::Graph::bars;
my %dataset = ( 1 => 3,
2 => 17,
3 => 34,
4 => 23,
5 => 25,
6 => 20,
7 => 12,
8 => 3,
9 => 1
);
# create new image
my $graph = new GD::Graph::bars(600, 300);
# discover maximum values of x and y for graph parameters
my( $xmax) = sort {$b <=> $a} keys %dataset;
my( $ymax) = sort {$b <=> $a} values %dataset;
# how many ticks to put on y axis
my $yticks = int($ymax / 5) + 1;
# define input arrays and enter 0 if undefined x value
my(@xsizes) = (0 .. $xmax);
my(@ycounts) = ();
foreach my $x (@xsizes) {
if ( defined $dataset{$x}) {
push @ycounts, $dataset{$x};
}else{
push @ycounts, 0;
}
}
# set parameters for graph
$graph->set(
transparent => 0,
title => "Summary of mutation data",
x_label => 'Mutants per cluster',
y_label => 'Number of mutants',
x_all_ticks => 1,
y_all_ticks => 0,
y_tick_number => $yticks,
zero_axis => 0,
zero_axis_only => 0,
);
# plot the data on the graph
my $gd = $graph->plot(
[ xsizes,
ycounts
]
);
# output file
my $pngfile = "gdgraph1.png";
unless(open(PNG, ">$pngfile")) {
croak "Cannot open $pngfile:$!\n";
}
# set output file handle PNG to binary stream
# (this is important sometimes, for example doing
# GCI programming on some operating systems
binmode PNG;
# print the image to the output file
print PNG $gd->png;

Figure 8-1 shows the image that is written to the file
gdgraph1.png. On my system it's
very small for an image, only 2028 bytes.


Figure 8-1. A simple bar graph



Here's how the code works. The new module is loaded
like so:

use GD::Graph::bars;

The dataset is then defined as a hash. In reality,
GD::Graph expects to see the data in arrays.
However, since your program may first collect data in a hash,
I've shown you how to incorporate hash data into a
GD::Graph image and included the code that
extracts the required x and y arrays from the hash.

Next, the module's new
constructor method is called to initialize a graph of type
bars and sized at 600 pixels horizontal and 300
pixels vertical.

# create new image
my $graph = new GD::Graph::bars(600, 300);

The next bit of code prepares some of the values needed to set
parameters for the graph. The maximum x and y values are extracted
from the hash %dataset. There is a way to specify
how many ticks are desired along the y axis, but if you want one
every five values, say, you have to figure out how many such values
will just fit the data: hence the $yticks
calculation.

# discover maximum values of x and y for graph parameters
my( $xmax) = sort {$b <=> $a} keys %dataset;
my( $ymax) = sort {$b <=> $a} values %dataset;
# how many ticks to put on y axis
my $yticks = int($ymax / 5) + 1;

Next, the actual arrays of x and y values are constructed from the
data in %dataset:

# define input arrays and enter 0 if undefined x value
my(@xsizes) = (0 .. $xmax);
my(@ycounts) = ();
foreach my $x (@xsizes) {
if ( defined $dataset{$x}) {
push @ycounts, $dataset{$x};
}else{
push @ycounts, 0;
}
}

Finally the various parameters are set (there are quite a few
possible parameters, as you'll see in the
documentation), the data is plotted in the graph, an output file
handle is created and set to binary mode (important for CGI web
programming), and the image data is written out.

Here is another version, gd2.pl, of the same program. This version
creates "lines and points" graphs
that have the values written over each datapoint. Instead of showing
the data as a bar, this graph shows data points joined by lines. The
data points have the value written next to them, except for the value
at x=3, which is suppressed. Other than that,
it's the same image from the same data as used in
gd1.pl.

#!/usr/bin/perl
#
# gd2.pl -- create GD::Graph "linespoints" graph
#
use strict;
use warnings;
use Carp;
use GD::Graph::linespoints;
my %dataset = ( 1 => 3,
2 => 17,
3 => 34,
4 => 23,
5 => 25,
6 => 20,
7 => 12,
8 => 3,
9 => 1
);
# create new image
my $graph = new GD::Graph::linespoints(600, 300);
# discover maximum values of x and y for graph parameters
my( $xmax) = sort {$b <=> $a} keys %dataset;
my( $ymax) = sort {$b <=> $a} values %dataset;
# how many ticks to put on y axis
my $yticks = int($ymax / 5) + 1;
# define input arrays and enter 0 if undefined x value
my(@xsizes) = (0 .. $xmax);
my(@ycounts) = ();
foreach my $x (@xsizes) {
if ( defined $dataset{$x}) {
push @ycounts, $dataset{$x};
}else{
push @ycounts, 0;
}
}
# define input data
# need to do separately so show_values will work
my $data = GD::Graph::Data->new(
[ xsizes,
ycounts
]
);
# use show_values to show values of data next to points
# use $values to suppress printing of value for x=3
my $values = $data->copy;
$values->set_y(1, 3, undef);
# set parameters for graph
$graph->set(
transparent => 0,
title => "Summary of mutation data",
x_label => 'Mutants per cluster',
y_label => 'Number of mutants',
x_all_ticks => 1,
y_all_ticks => 0,
y_tick_number => $yticks,
zero_axis => 0,
zero_axis_only => 0,
show_values => $values,
);
# plot the data on the graph
my $gd = $graph->plot(
[ xsizes,
ycounts
]
);
# output file
my $pngfile = "gdgraph2.png";
unless(open(PNG, ">$pngfile")) {
croak "Cannot open $pngfile:$!\n";
}
binmode PNG;
print PNG $gd->png;

Figure 8-2 shows the image that's written to the
file gdgraph2.png.


Figure 8-2. A lines and points graph



A variety of image viewing programs may be used to display your
results while you're doing graphics programming.
ImageMagick has a display program called display
that runs on a Linux system and elsewhere. I often use
xv, and while it usually works quite well, it
seems to have trouble with PNG files. When programming,
it's a good idea to pick an imaging program that can
be set to automatically update the display when you overwrite the
image file with new data. It's common for a
system's user interface to allow you to click on the
image file's name or thumbnail image in order to
launch an image viewing program with the image loaded.

This section just gives you a taste of the capabilities of
GD::Graph. The module provides many possibilities,
all of which are easily incorporated into your Perl programs for
output to files or sent to a web browser from your CGI
program.


/ 156