~ubuntu-branches/ubuntu/oneiric/bioperl/oneiric

« back to all changes in this revision

Viewing changes to doc/howto/html/Graphics-HOWTO.html

  • Committer: Bazaar Package Importer
  • Author(s): Matt Hope
  • Date: 2004-04-18 14:24:11 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040418142411-gr92uexquw4w8liq
Tags: 1.4-1
* New upstream release
* Examples and working code are installed by default to usr/bin,
  this has been moved to usr/share/doc/bioperl/bin

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="ISO-8859-1"?>
 
2
<!DOCTYPE html
 
3
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
4
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Bio::Graphics HOWTO</title><link rel="stylesheet" href="e-novative.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.55.0"/><meta name="description" content="&#xA;This HOWTO describes how to render sequence data graphically in a&#xA;horizontal map.  It applies to a variety of situations ranging from&#xA;rendering the feature table of a GenBank entry, to graphing the&#xA;positions and scores of a BLAST search, to rendering a clone map.  It&#xA;describes the programmatic interface to the Bio::Graphics module, and&#xA;discusses how to create dynamic web pages using Bio::DB::GFF and the&#xA;gbrowse package.&#xA;"/></head><body><div class="article"><div class="titlepage"><div><h1 class="title"><a id="d3e1"/>Bio::Graphics HOWTO</h1></div><div><div class="author"><h3 class="author">Lincoln Stein</h3><div class="affiliation"><span class="orgname">
 
5
                        <a href="http://www.cshl.org" target="_top">Cold Spring Harbor Laboratory</a>
 
6
                <br/></span><div class="address"><p>
 
7
                        <tt>&lt;<a href="mailto:lstein@cshl.org">lstein@cshl.org</a>&gt;</tt>
 
8
                </p></div></div></div></div><div><div class="legalnotice"><p>
 
9
        This document is copyright Lincoln Stein, 2002.  It can
 
10
        be copied and distributed under the terms of the Perl
 
11
        Artistic License.
 
12
</p></div></div><div><p class="pubdate">2002-09-01</p></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="3"><b>Revision History</b></th></tr><tr><td align="left">Revision 0.2</td><td align="left">2003-05-15</td><td align="left">lds</td></tr><tr><td align="left" colspan="3">Current as of BioPerl 1.2.2</td></tr></table></div></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="3"><b>Revision History</b></th></tr><tr><td align="left">Revision 0.3</td><td align="left">2003-09-17</td><td align="left">BIO</td></tr><tr><td align="left" colspan="3">Current as of BioPerl 1.2.3</td></tr></table></div></div><div><div class="abstract"><p class="title"><b>Abstract</b></p><p>
 
13
This HOWTO describes how to render sequence data graphically in a
 
14
horizontal map.  It applies to a variety of situations ranging from
 
15
rendering the feature table of a GenBank entry, to graphing the
 
16
positions and scores of a BLAST search, to rendering a clone map.  It
 
17
describes the programmatic interface to the Bio::Graphics module, and
 
18
discusses how to create dynamic web pages using Bio::DB::GFF and the
 
19
gbrowse package.
 
20
</p></div></div><hr/></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1.�<a href="#intro">Introduction</a></dt><dt>2.�<a href="#prelim">Preliminaries</a></dt><dt>3.�<a href="#gettingStarted">Getting Started</a></dt><dt>4.�<a href="#addingscale">Adding a Scale to the Image</a></dt><dt>5.�<a href="#improving">Improving the Image</a></dt><dt>6.�<a href="#parsing-blast">Parsing Real BLAST Output</a></dt><dt>7.�<a href="#rendering-features">Rendering Features from a GenBank or EMBL File</a></dt><dt>8.�<a href="#rendering-features-better">A Better Version of the Feature Renderer</a></dt><dt>9.�<a href="#summary">Summary</a></dt></dl></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a id="intro"/>1.�Introduction</h2></div></div><p>
 
21
This HOWTO describes the Bio::Graphics module, and some of the
 
22
applications that were built on top of it.  Bio::Graphics was designed
 
23
to solve the following common problems:
 
24
</p><div class="itemizedlist"><ul type="disc"><li><p>
 
25
You have a list of BLAST hits on a sequence and you want to
 
26
generate a picture that shows where the hits go and what their score
 
27
is.
 
28
</p></li><li><p>
 
29
You have a big GenBank file with a complex feature table, and
 
30
you want to render the positions of the genes, repeats, promoters 
 
31
and other features.
 
32
</p></li><li><p>
 
33
You have a list of ESTs that you've mapped to a genome, and you want
 
34
to show how they align.
 
35
</p></li><li><p>
 
36
You have created a clone fingerprint map, and you want to display it.
 
37
</p></li></ul></div><p>
 
38
The Bio::Graphics module was designed to solve these problems.  In
 
39
addition, using the Bio::DB::GFF module (part of BioPerl) and the
 
40
gbrowse program (available from http://www.gmod.org) you can create
 
41
interactive web pages to explore your data.
 
42
</p><p>
 
43
This document takes you through a few common applications of
 
44
Bio::Graphics in a cookbook fashion.
 
45
</p></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a id="prelim"/>2.�Preliminaries</h2></div></div><p>
 
46
Bio::Graphics is dependent on GD, a Perl module for generating
 
47
bitmapped graphics written by the author.  GD in turn is dependent on
 
48
libgd, a C library written by Thomas Boutell, formerly also of Cold
 
49
Spring Harbor Laboratory (www.boutell.com/gd). To use Bio::Graphics, 
 
50
you must have both these software libraries installed.
 
51
</p><p>
 
52
If you are on a Linux system, you might already have GD installed.  To
 
53
verify, run the following command:
 
54
</p><p>
 
55
<pre class="programlisting">
 
56
 % perl -MGD -e 'print $GD::VERSION';
 
57
</pre>
 
58
</p><p>
 
59
If the program prints out a version number, you are in luck.
 
60
Otherwise, if you get a "Can't locate GD.pm" error, you'll have to
 
61
install the module.  For users of ActiveState Perl this is very easy.
 
62
Just start up the PPM program and issue the command "install GD".  For
 
63
users of other versions of Perl, you should go to www.cpan.org,
 
64
download a recent version of the GD module, unpack it, and follow the
 
65
installation directions.  You may also need to upgrade to a recent
 
66
version of the libgd C library.
 
67
</p><p>
 
68
If the program prints out a version number, you are in luck.
 
69
Otherwise, if you get a "Can't locate GD.pm" error, you'll have to
 
70
install the module.  For users of ActiveState Perl this is very easy.
 
71
Just start up the PPM program and issue the command "install GD".  For
 
72
users of other versions of Perl, you should go to www.cpan.org,
 
73
download a recent version of the GD module, unpack it, and follow the
 
74
installation directions.
 
75
 
 
76
</p><p>
 
77
You may need to upgrade to a recent version of the libgd C library.
 
78
At the time this was written, there were two versions of libgd.  libgd
 
79
version 1.8.4 is the stable version, and corresponds to GD version
 
80
1.43.  libgd version 2.0.1 is the beta version; although it has many
 
81
cool features, it also has a few known bugs (which Bio::Graphics works
 
82
around).  If you use libgd 2.0.1 or higher, be sure it matches GD
 
83
version 2.0.1 or higher.
 
84
</p><p>
 
85
You will also need to install the Text::Shellwords module, which is
 
86
available from CPAN.
 
87
</p></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a id="gettingStarted"/>3.�Getting Started</h2></div></div><p>
 
88
All the code examples and BLAST input files we'll use are available in
 
89
the doc/howto/examples/graphics directory in the BioPerl package. 
 
90
</p><p>
 
91
Our first example will be rendering a table of BLAST hits on a
 
92
sequence that is exactly 1000 residues long. For now, we're ignoring
 
93
finicky little details like HSPs, and assume that each hit is a single
 
94
span from start to end.  Also, we'll be using the BLAST score rather
 
95
than P or E value.  Later on, we'll switch to using real BLAST output
 
96
parsed by the Bio::SearchIO module, but for now, our table looks like
 
97
this:
 
98
</p><p>
 
99
<div class="figure"><a id="d3e58"/><pre class="programlisting">
 
100
# hit           score   start   end
 
101
hsHOX3          381     2       200
 
102
scHOX3          210     2       210
 
103
xlHOX3          800     2       200
 
104
hsHOX2          1000    380     921
 
105
scHOX2          812     402     972
 
106
xlHOX2          1200    400     970
 
107
BUM             400     300     620
 
108
PRES1           127     310     700
 
109
</pre><p class="title"><b>Figure�1.�Simple blast hit file (data1.txt)</b></p></div>
 
110
</p><p>
 
111
Our first attempt to parse and render this file looks like this:
 
112
</p><p>
 
113
<div class="example"><a id="code1"/><p class="title"><b>Example�1.�Rendering the simple blast hit file (render_blast1.pl)</b></p><pre class="programlisting">
 
114
  0  #!/usr/bin/perl
 
115
 
 
116
  1  # This is code example 1 in the Graphics-HOWTO
 
117
  2  use strict;
 
118
  3  use Bio::Graphics;
 
119
  4  use Bio::SeqFeature::Generic;
 
120
 
 
121
  5  my $panel = Bio::Graphics::Panel-&gt;new(-length =&gt; 1000,-width  =&gt; 800);
 
122
  6  my $track = $panel-&gt;add_track(-glyph =&gt; 'generic',-label  =&gt; 1);
 
123
 
 
124
  7  while (&lt;&gt;) { # read blast file
 
125
  8    chomp;
 
126
  9    next if /^\#/;  # ignore comments
 
127
 10    my($name,$score,$start,$end) = split /\t+/;
 
128
 11    my $feature = Bio::SeqFeature::Generic-&gt;new(-display_name=&gt;$name,-score=&gt;$score,
 
129
 12                                                -start=&gt;$start,-end=&gt;$end);
 
130
 13    $track-&gt;add_feature($feature);
 
131
 14  }
 
132
 
 
133
 15  print $panel-&gt;png;
 
134
</pre></div>
 
135
</p><p>
 
136
The script begins by loading the Bio::Graphics module (line 3), which
 
137
in turn brings in a number of other modules that we'll use later.  We
 
138
also load <tt>Bio::SeqFeature::Generic</tt> in order to
 
139
create a series of Bio::SeqFeatureI objects for rendering.  We then
 
140
create a Bio::Graphics::Panel object by calling its new() method,
 
141
specifying that the panel is to correspond to a sequence that is 1000
 
142
nucleotides long, and has a physical width of 800 pixels (line 5).
 
143
The Panel can contain multiple horizontal tracks, each of which has
 
144
its own way of rendering features (called a "glyph"), color, labeling
 
145
convention, and so forth.  In this simple example, we create a single
 
146
track by calling the panel object's add_track() method (line 6),
 
147
specify a glyph type of "generic", and ask that the objects in the
 
148
track be labeled by providing a true value to the -label argument.
 
149
This gives us a track object that we can add our hits to.
 
150
</p><p>
 
151
We're now ready to render the blast hit file.  We loop through it
 
152
(line 7-14), stripping off the comments, and parsing out the name,
 
153
score and range (line 10).  We now need a Bio::SeqFeatureI object to
 
154
place in the track.  The easiest way to do this is to create a
 
155
Bio::SeqFeature::Generic object, which is similar to Bio::PrimarySeq,
 
156
except that it provides a way of attaching start and end positions to
 
157
the sequence, as well as such nebulous but useful attributes as the
 
158
"score" and "source".  The Bio::SeqFeature::Generic-&gt;new() method,
 
159
invoked in line 11, takes arguments corresponding to the name of each
 
160
hit, its start and end coordinates, and its score.
 
161
</p><p>
 
162
After creating the feature object, we add it to the track by calling
 
163
the track's add_feature() method (line 13).
 
164
</p><p>
 
165
After processing all the hits, we call the panel's png() method to
 
166
render them and convert it into a Portable Network Graphics file, the
 
167
contents of which are printed to standard output.  We can now view the
 
168
result by piping it to our favorite image display program.
 
169
</p><p>
 
170
IMPORTANT NOTE: If you are on a Windows platform, you need to put
 
171
STDOUT into binary mode so that the PNG file does not go through
 
172
Window's carriage return/linefeed transformations.  Before the
 
173
final print statement, put the statement "binmode(STDOUT)".
 
174
</p><p>
 
175
This advice also applies to certain versions of RedHat, which ship
 
176
with a patched (and possibly broken) version of Perl.
 
177
</p><p>
 
178
<div class="figure"><a id="d3e74"/><pre class="programlisting">
 
179
% render_blast1.pl data1.txt | display -
 
180
</pre><div class="mediaobject"><img src="../figs/graphics/fig1.png"/></div><p class="title"><b>Figure�2.�Rendering BLAST hits</b></p></div>
 
181
</p><p>
 
182
Users of operating systems that don't support pipes can simply
 
183
redirect the output to a file and view it in their favorite image
 
184
program.
 
185
</p></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a id="addingscale"/>4.�Adding a Scale to the Image</h2></div></div><p>
 
186
This is all very nice, but it's missing two essential components:
 
187
</p><div class="itemizedlist"><ul type="disc"><li><p>It doesn't have a scale.</p></li><li><p>It doesn't distinguish between hits with different
 
188
scores.
 
189
</p></li></ul></div><p>Example 2 fixes these problems</p><p>
 
190
<div class="example"><a id="code2"/><p class="title"><b>Example�2.�Rendering the blast hit file with scores and scale</b></p><pre class="programlisting">
 
191
  0  #!/usr/bin/perl
 
192
 
 
193
  1  # This is code example 2 in the Graphics-HOWTO
 
194
  2  use strict;
 
195
  3  use lib '/home/lstein/projects/bioperl-live';
 
196
  4  use Bio::Graphics;
 
197
  5  use Bio::SeqFeature::Generic;
 
198
 
 
199
  6  my $panel = Bio::Graphics::Panel-&gt;new(-length =&gt; 1000,
 
200
  7                                        -width  =&gt; 800,
 
201
  8                                        -pad_left =&gt; 10,
 
202
  9                                        -pad_right =&gt; 10,
 
203
 10                                       );
 
204
 11  my $full_length = Bio::SeqFeature::Generic-&gt;new(-start=&gt;1,-end=&gt;1000);
 
205
 12  $panel-&gt;add_track($full_length,
 
206
 13                    -glyph   =&gt; 'arrow',
 
207
 14                    -tick    =&gt; 2,
 
208
 15                    -fgcolor =&gt; 'black',
 
209
 16                    -double  =&gt; 1,
 
210
 17                   );
 
211
 
 
212
 18  my $track = $panel-&gt;add_track(-glyph =&gt; 'graded_segments',
 
213
 19                                -label  =&gt; 1,
 
214
 20                                -bgcolor =&gt; 'blue',
 
215
 21                                -min_score =&gt; 0,
 
216
 22                                -max_score =&gt; 1000);
 
217
 
 
218
 23  while (&lt;&gt;) { # read blast file
 
219
 24    chomp;
 
220
 25    next if /^\#/;  # ignore comments
 
221
 26    my($name,$score,$start,$end) = split /\t+/;
 
222
 27    my $feature = Bio::SeqFeature::Generic-&gt;new(-display_name=&gt;$name,-score=&gt;$score,
 
223
 28                                                -start=&gt;$start,-end=&gt;$end);
 
224
 29    $track-&gt;add_feature($feature);
 
225
 30  }
 
226
 
 
227
 31  print $panel-&gt;png;
 
228
</pre></div>
 
229
</p><p>
 
230
There are several changes to look at.  The first is minor.  We'd like
 
231
to put a boundary around the left and right edges of the image so that
 
232
the features don't bump up against the margin, so we specify a 10
 
233
pixel leeway with the <i><tt>-pad_left</tt></i> and
 
234
<i><tt>-pad_right</tt></i> arguments in lines 8 and 9.
 
235
</p><p>
 
236
The next change is more subtle.  We want to draw a scale all the way
 
237
across the image.  To do this, we create a track to contain the scale,
 
238
and a feature that spans the track from the start to the end.  Line 11
 
239
creates the feature, giving its start and end coordinates.  Lines
 
240
12-17 create a new track containing this feature.  Unlike the previous
 
241
example, in which we created the track first and then added features
 
242
one at a time with add_feature(), we show here how to add feature(s)
 
243
directly in the call to add_track().  If the first argument to
 
244
add_track is either a single feature or a feature array ref, then
 
245
add_track() will automatically incorporate the feature(s) into the
 
246
track in a single efficient step.  The remainder of the arguments
 
247
configure the track as before.  The -glyph argument says to use the
 
248
"arrow" glyph.  The -tick argument indicates that the arrow should
 
249
contain tick marks, and that both major and minor ticks should be
 
250
shown (tick type of "2").  We set the foreground color to black, and
 
251
request that arrows should be placed at both ends (-double =&gt;1).
 
252
</p><p>
 
253
<sup>[<a id="d3e99" href="#ftn.d3e99">1</a>]</sup>
 
254
</p><p>
 
255
In lines 18-22, we get a bit fancier with the blast hit track.  Now,
 
256
instead of creating a generic glyph, we use the "graded_segments"
 
257
glyph.  This glyph takes the specified background color for the
 
258
feature, and either darkens or lightens it according to its score.  We
 
259
specify the base background color (-bgcolor =&gt; 'blue'), and the
 
260
minimum and maximum scores to scale to (-min_score and -max_score).
 
261
(You may need to experiment with the min and max scores in order to get
 
262
the glyph to scale the colors the way you want.)  The remainder of the
 
263
program is the same.
 
264
</p><p>
 
265
When we run the modified script, we get this image.
 
266
</p><p>
 
267
<div class="figure"><a id="d3e104"/><div class="mediaobject"><img src="../figs/graphics/fig2.png"/></div><p class="title"><b>Figure�3.�The improved image</b></p></div>
 
268
</p><p>
 
269
IMPORTANT NOTE: Remember that if you are on a Windows platform, you need to put
 
270
STDOUT into binary mode so that the PNG file does not go through
 
271
Window's carriage return/linefeed transformations.  Before the
 
272
final print statement, write binmode(STDOUT).
 
273
</p></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a id="improving"/>5.�Improving the Image</h2></div></div><p>
 
274
Before we move into displaying gapped alignments, let's tweak the
 
275
image slightly so that higher scoring hits appear at the top of the
 
276
image, and the score itself is printed in red underneath each hit.
 
277
The changes are shown in Example 3.
 
278
</p><p>
 
279
<div class="example"><a id="code3"/><p class="title"><b>Example�3.�Rendering the blast hit file with scores and scale</b></p><pre class="programlisting">
 
280
  0  #!/usr/bin/perl
 
281
 
 
282
  1  # This is code example 3 in the Graphics-HOWTO
 
283
  2  use strict;
 
284
  3  use lib '/home/lstein/projects/bioperl-live';
 
285
  4  use Bio::Graphics;
 
286
  5  use Bio::SeqFeature::Generic;
 
287
 
 
288
  6  my $panel = Bio::Graphics::Panel-&gt;new(-length =&gt; 1000,
 
289
  7                                        -width  =&gt; 800,
 
290
  8                                        -pad_left =&gt; 10,
 
291
  9                                        -pad_right =&gt; 10,
 
292
 10                                       );
 
293
 11  my $full_length = Bio::SeqFeature::Generic-&gt;new(-start=&gt;1,-end=&gt;1000);
 
294
 12  $panel-&gt;add_track($full_length,
 
295
 13                    -glyph   =&gt; 'arrow',
 
296
 14                    -tick    =&gt; 2,
 
297
 15                    -fgcolor =&gt; 'black',
 
298
 16                    -double  =&gt; 1,
 
299
 17                   );
 
300
 
 
301
 18  my $track = $panel-&gt;add_track(-glyph =&gt; 'graded_segments',
 
302
 19                                -label  =&gt; 1,
 
303
 20                                -bgcolor =&gt; 'blue',
 
304
 21                                -min_score =&gt; 0,
 
305
 22                                -max_score =&gt; 1000,
 
306
 23                                -font2color     =&gt; 'red',
 
307
 24                                -sort_order     =&gt; 'high_score',
 
308
 25                                -description =&gt; sub {
 
309
 26                                  my $feature = shift;
 
310
 27                                  my $score   = $feature-&gt;score;
 
311
 28                                  return "score=$score";
 
312
 29                                 });
 
313
 
 
314
 30  while (&lt;&gt;) { # read blast file
 
315
 31    chomp;
 
316
 32    next if /^\#/;  # ignore comments
 
317
 33    my($name,$score,$start,$end) = split /\t+/;
 
318
 34    my $feature = Bio::SeqFeature::Generic-&gt;new(-score=&gt;$score,
 
319
 35                                                -display_name=&gt;$name,
 
320
 36                                                -start=&gt;$start,-end=&gt;$end);
 
321
 37    $track-&gt;add_feature($feature);
 
322
 38  }
 
323
 
 
324
 39  print $panel-&gt;png;
 
325
</pre></div>
 
326
</p><p>
 
327
There are two changes to look at.  The first appears in line 24, where
 
328
we pass the <i><tt>-sort_order</tt></i> option to the call that
 
329
creates the blast hit track.  <i><tt>-sort_order</tt></i>
 
330
changes the way that features sort from top to bottom, and will accept
 
331
a number of prepackaged sort orders or a coderef for custom sorting.
 
332
In this case, we pass a prepackaged sort order of
 
333
<i><tt>high_score</tt></i>, which sorts the hits from top to
 
334
bottom in reverse order of their score.
 
335
</p><p>
 
336
The second change is more complicated, and involves the -description
 
337
option that appears in the <tt>add_track()</tt> call on
 
338
lines 25-28.  The value of <i><tt>-description</tt></i> will be
 
339
printed beneath each feature.  We could pass
 
340
<i><tt>-description</tt></i> a constant string, but that would
 
341
simply print the same string under each feature.  Instead we pass
 
342
<i><tt>-description</tt></i> a code reference to a subroutine
 
343
that will be invoked while the picture is being rendered.  This
 
344
subroutine will be passed the current feature, and must return the
 
345
string to use as the value of the description.  In our code, we simply
 
346
fetch out the BLAST hit's score using its <tt>score()</tt>
 
347
method, and incorporate that into the description string.
 
348
</p><div class="tip"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"/></td><th>Tip</th></tr><tr><td colspan="2" align="left" valign="top"><p>
 
349
The ability to use a code reference as a configuration option isn't
 
350
unique to <i><tt>-description</tt></i>.  In fact, you can use a code reference for any
 
351
of the options passed to add_track().
 
352
</p></td></tr></table></div><p>
 
353
Another minor change is the use of
 
354
<i><tt>-font2color</tt></i> in line 23. This simply
 
355
sets the color used for the description strings.  Figure 3 shows the
 
356
effect of these changes.
 
357
</p><p>
 
358
<div class="figure"><a id="d3e133"/><div class="mediaobject"><img src="../figs/graphics/fig3.png"/></div><p class="title"><b>Figure�4.�The image with descriptions and sorted hits</b></p></div>
 
359
</p></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a id="parsing-blast"/>6.�Parsing Real BLAST Output</h2></div></div><p>
 
360
From here it's just a small step to writing a general purpose utility
 
361
that will read a BLAST file, parse its output, and output a picture.
 
362
The key is to use the <tt>Bio::SearchIO</tt>
 
363
infrastructure because it produces Bio::SeqFeatureI similarity hits
 
364
that can be rendered directly by <tt>Bio::Graphics</tt>.
 
365
</p><p>
 
366
Code example 4 shows the new utility.
 
367
</p><p>
 
368
<div class="example"><a id="code4"/><p class="title"><b>Example�4.�Parsing and Rendering a Real BLAST File with Bio::SearchIO</b></p><pre class="programlisting">
 
369
  0  #!/usr/bin/perl
 
370
 
 
371
  1  # This is code example 4 in the Graphics-HOWTO
 
372
  2  use strict;
 
373
  3  use lib "$ENV{HOME}/projects/bioperl-live";
 
374
  4  use Bio::Graphics;
 
375
  5  use Bio::SearchIO;
 
376
 
 
377
  6  my $file = shift or die "Usage: render_blast4.pl &lt;blast file&gt;\n";
 
378
 
 
379
  7  my $searchio = Bio::SearchIO-&gt;new(-file   =&gt; $file,
 
380
  8                                       -format =&gt; 'blast') or die "parse failed";
 
381
 
 
382
 
 
383
  9  my $result = $searchio-&gt;next_result() or die "no result";
 
384
 
 
385
 10  my $panel = Bio::Graphics::Panel-&gt;new(-length    =&gt; $result-&gt;query_length,
 
386
 11                                        -width     =&gt; 800,
 
387
 12                                        -pad_left  =&gt; 10,
 
388
 13                                        -pad_right =&gt; 10,
 
389
 14                                       );
 
390
 
 
391
 15  my $full_length = Bio::SeqFeature::Generic-&gt;new(-start=&gt;1,-end=&gt;$result-&gt;query_length,
 
392
 16                                                  -display_name=&gt;$result-&gt;query_name);
 
393
 17  $panel-&gt;add_track($full_length,
 
394
 18                    -glyph   =&gt; 'arrow',
 
395
 19                    -tick    =&gt; 2,
 
396
 20                    -fgcolor =&gt; 'black',
 
397
 21                    -double  =&gt; 1,
 
398
 22                    -label   =&gt; 1,
 
399
 23                   );
 
400
 
 
401
 24  my $track = $panel-&gt;add_track(-glyph       =&gt; 'graded_segments',
 
402
 25                                -label       =&gt; 1,
 
403
 26                                -connector   =&gt; 'dashed',
 
404
 27                                -bgcolor     =&gt; 'blue',
 
405
 28                                -font2color  =&gt; 'red',
 
406
 29                                -sort_order  =&gt; 'high_score',
 
407
 30                                -description =&gt; sub {
 
408
 31                                  my $feature = shift;
 
409
 32                                  return unless $feature-&gt;has_tag('description');
 
410
 33                                  my ($description) = $feature-&gt;each_tag_value('description');
 
411
 34                                  my $score = $feature-&gt;score;
 
412
 35                                  "$description, score=$score";
 
413
 36                                 });
 
414
 
 
415
 37  while( my $hit = $result-&gt;next_hit ) {
 
416
 38    next unless $hit-&gt;significance &lt; 1E-20;
 
417
 39    my $feature = Bio::SeqFeature::Generic-&gt;new(-score   =&gt; $hit-&gt;raw_score,
 
418
 40                                                -display_name =&gt; $hit-&gt;name,
 
419
 41                                                -tag     =&gt; {
 
420
 42                                                             description =&gt; $hit-&gt;description
 
421
 43                                                            },
 
422
 44                                               );
 
423
 45    while( my $hsp = $hit-&gt;next_hsp ) {
 
424
 46      $feature-&gt;add_sub_SeqFeature($hsp,'EXPAND');
 
425
 47    }
 
426
 
 
427
 48    $track-&gt;add_feature($feature);
 
428
 49  }
 
429
 
 
430
 50  print $panel-&gt;png;
 
431
</pre></div>
 
432
</p><p>
 
433
In lines 6-8 we read the name of the file that contains the BLAST
 
434
results from the command line, and pass it to
 
435
<tt>Bio::SearchIO-&gt;new()</tt>, returning a
 
436
<tt>Bio::SearchIO</tt> object.  We read a single result
 
437
from the searchIO object (line 9).  This assumes that the BLAST output
 
438
file contains a single run of BLAST only.
 
439
</p><p>
 
440
We then initialize the panel and tracks as before.  The only change
 
441
here is in lines 24-36, where we create the track for the BLAST hits.
 
442
The <i><tt>-description</tt></i> option has now been enhanced
 
443
to create a line of text that incorporates the "description" tag from
 
444
the feature object as well as its similarity score.  There's also a
 
445
slight change in line 26, where we introduce the
 
446
<i><tt>-connector</tt></i> option.  This allows us to configure a
 
447
line that connects the segments of a discontinuous feature, such as
 
448
the HSPs in a BLAST hit.  In this case, we asked the rendering engine
 
449
to produce a dashed connector line.
 
450
</p><p>
 
451
The remainder of the script retrieves each of the hits from the BLAST
 
452
file, creates a Feature object representing the hit, and then
 
453
retrieves each HSP and incorporates it into the feature.  Line 37
 
454
begins a <tt>while()</tt> loop that retrieves each of the
 
455
similarity hits in turn.  We filter the hit by its significance,
 
456
throwing out any that have an expectation value greater than 1E-20
 
457
(you will have to adjust this in your own utilities).  We then use the
 
458
information in the hit to construct a
 
459
<tt>Bio::SeqFeature::Generic</tt> object (lines 39-44).
 
460
Notice how the name of the hit and the score are used to initialize
 
461
the feature, and how the description is turned into a tag named
 
462
"description."
 
463
</p><p>
 
464
The start and end bounds of the hit are determined by the union of its
 
465
HSPs.  We loop through each of the hit's HSPs by calling its
 
466
<tt>next_hsp()</tt> method, and add each HSP to the
 
467
newly-created hit feature by calling the feature's
 
468
<tt>add_sub_SeqFeature()</tt> method (line 46).  The
 
469
<i><tt>EXPAND</tt></i> parameter instructs the feature to
 
470
expand its start and end coordinates to enclose the added subfeature.
 
471
</p><p>
 
472
Once all the HSPs are added to the feature, we insert the feature into
 
473
the track as before using the track's
 
474
<tt>add_feature()</tt> function.
 
475
</p><p>
 
476
Figure 4 shows the output from a sample BLAST hit file.
 
477
</p><p>
 
478
<div class="figure"><a id="d3e165"/><div class="mediaobject"><img src="../figs/graphics/fig4.png"/></div><p class="title"><b>Figure�5.�Output from the BLAST parsing and rendering script</b></p></div>
 
479
</p><p>
 
480
The next section will demonstrate how to parse and display feature
 
481
tables from GenBank and EMBL.
 
482
</p><p>
 
483
IMPORTANT NOTE: Remember that if you are on a Windows platform, you need to put
 
484
STDOUT into binary mode so that the PNG file does not go through
 
485
Window's carriage return/linefeed transformations.  Before the
 
486
final print statement, write binmode(STDOUT).
 
487
</p></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a id="rendering-features"/>7.�Rendering Features from a GenBank or EMBL File</h2></div></div><p>
 
488
With <tt>Bio::Graphics</tt> you can render the feature
 
489
table of a GenBank or EMBL file quite easily.  The trick is to use
 
490
<tt>Bio::SeqIO</tt> to generate a set of
 
491
<tt>Bio::SeqFeatureI</tt> objects, and to use those
 
492
features to populate tracks. For simplicity's sake, we will sort each
 
493
feature by its primary tag (such as "exon") and create a new track for
 
494
each tag type.
 
495
</p><p>
 
496
Code example 5 shows the code for rendering an EMBL or GenBank entry.
 
497
</p><p>
 
498
<div class="example"><a id="code5"/><p class="title"><b>Example�5.�The embl2picture.pl script turns any EMBL or GenBank entry into a graphical rendering</b></p><pre class="programlisting">
 
499
  0  #!/usr/bin/perl
 
500
 
 
501
  1  # file: embl2picture.pl
 
502
  2  # This is code example 5 in the Graphics-HOWTO
 
503
  3  # Author: Lincoln Stein
 
504
 
 
505
  4  use strict;
 
506
  5  use lib "$ENV{HOME}/projects/bioperl-live";
 
507
  6  use Bio::Graphics;
 
508
  7  use Bio::SeqIO;
 
509
  8  use Bio::SeqFeature::Generic;
 
510
 
 
511
  9  my $file = shift                       or die "provide a sequence file as the argument";
 
512
 10  my $io = Bio::SeqIO-&gt;new(-file=&gt;$file) or die "couldn't create Bio::SeqIO";
 
513
 11  my $seq = $io-&gt;next_seq                or die "couldn't find a sequence in the file";
 
514
 12  my $wholeseq = Bio::SeqFeature::Generic-&gt;new(-start=&gt;1,-end=&gt;$seq-&gt;length,
 
515
 13                                               -display_name=&gt;$seq-&gt;display_name);
 
516
 
 
517
 14  my @features = $seq-&gt;all_SeqFeatures;
 
518
 
 
519
 15  # partition features by their primary tags
 
520
 16  my %sorted_features;
 
521
 17  for my $f (@features) {
 
522
 18    my $tag = $f-&gt;primary_tag;
 
523
 19    push @{$sorted_features{$tag}},$f;
 
524
 20  }
 
525
 
 
526
 21  my $panel = Bio::Graphics::Panel-&gt;new(
 
527
 22                                        -length    =&gt; $seq-&gt;length,
 
528
 23                                        -key_style =&gt; 'between',
 
529
 24                                        -width     =&gt; 800,
 
530
 25                                        -pad_left  =&gt; 10,
 
531
 26                                        -pad_right =&gt; 10,
 
532
 27                                        );
 
533
 28  $panel-&gt;add_track($wholeseq,
 
534
 29                    -glyph =&gt; 'arrow',
 
535
 30                    -bump =&gt; 0,
 
536
 31                    -double=&gt;1,
 
537
 32                    -tick =&gt; 2);
 
538
 
 
539
 33  $panel-&gt;add_track($wholeseq,
 
540
 34                    -glyph  =&gt; 'generic',
 
541
 35                    -bgcolor =&gt; 'blue',
 
542
 36                    -label  =&gt; 1,
 
543
 37                   );
 
544
 
 
545
 38  # general case
 
546
 39  my @colors = qw(cyan orange blue purple green chartreuse magenta yellow aqua);
 
547
 40  my $idx    = 0;
 
548
 41  for my $tag (sort keys %sorted_features) {
 
549
 42    my $features = $sorted_features{$tag};
 
550
 43    $panel-&gt;add_track($features,
 
551
 44                      -glyph    =&gt;  'generic',
 
552
 45                      -bgcolor  =&gt;  $colors[$idx++ % @colors],
 
553
 46                      -fgcolor  =&gt; 'black',
 
554
 47                      -font2color =&gt; 'red',
 
555
 48                      -key      =&gt; "${tag}s",
 
556
 49                      -bump     =&gt; +1,
 
557
 50                      -height   =&gt; 8,
 
558
 51                      -label    =&gt; 1,
 
559
 52                      -description =&gt; 1,
 
560
 53                     );
 
561
 54  }
 
562
 
 
563
 55  print $panel-&gt;png;
 
564
 56  exit 0;
 
565
</pre></div>
 
566
</p><p>
 
567
The way this script works is simple.  After the library load preamble,
 
568
the script reads the name of the GenBank or EMBL file from the command
 
569
line (line 8).  It passes the filename to
 
570
<tt>Bio::SeqIO</tt>'s <tt>new()</tt> method,
 
571
and reads the first sequence object from it (lines 9-11).  If anything
 
572
goes wrong, the script dies with an error message.
 
573
</p><p>
 
574
The returned object is a Bio::SeqI object, which has a length but no
 
575
defined start or end coordinates.  We would like to create a drawable
 
576
Bio::SeqFeatureI object to use for the scale, so we generate a new
 
577
Bio::SeqFeature::Generic object that goes from a start of 1 to the
 
578
length of the sequence. (lines 12-13).
 
579
</p><p>
 
580
The script reads the features from the sequence object by calling
 
581
<tt>all_SeqFeatures()</tt>, and then sorts each feature by
 
582
its primary tag into a hash of array references named
 
583
<tt>%sorted_features</tt> (lines 14-20).
 
584
</p><p>
 
585
Next, we create the <tt>Bio::Graphics::Panel</tt> object
 
586
(lines 21-27).  As in previous examples, we specify the width of the
 
587
image, as well as some extra white space to pad out the left and right
 
588
borders.
 
589
</p><p>
 
590
We now add two tracks, one for the scale (lines 28-32) and the other
 
591
for the sequence as a whole (33-37).  As in the earlier examples, we
 
592
pass <tt>add_track()</tt> the sequence object as the first
 
593
argument before the options so that the object is incorporated into
 
594
the track immediately.
 
595
</p><p>
 
596
We are now ready to create a track for each feature type.  In order to
 
597
distinguish the tracks by color, we initialize an array of 9 color
 
598
names and simply cycle through them (lines 39-54).  For each feature
 
599
tag, we retrieve the corresponding list of features from
 
600
<tt>%sorted_features</tt> (line 42) and create a track for
 
601
it using the "generic" glyph and the next color in the list (lines
 
602
43-53).  We set the <tt>-label</tt> and
 
603
<tt>-description</tt> options to the value "1".  This signals
 
604
<tt>Bio::Graphics</tt> that it should do the best it can
 
605
to choose useful label and description values on its own.
 
606
</p><p>
 
607
After adding all the feature types, we call the panel's
 
608
<tt>png()</tt> method to generate a graphic file, which we
 
609
print to STDOUT.  If we are on a Windows platform, we would have to include
 
610
<tt>binmode(STDOUT)</tt> prior to this statement in order to
 
611
avoid Windows textmode carriage return/linefeed transformations.
 
612
</p><p>
 
613
Figure 5 shows an example of the output of this script.
 
614
</p><p>
 
615
<div class="figure"><a id="d3e204"/><div class="mediaobject"><img src="../figs/graphics/fig5.png"/></div><p class="title"><b>Figure�6.�The embl2picture.pl script</b></p></div>
 
616
</p></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a id="rendering-features-better"/>8.�A Better Version of the Feature Renderer</h2></div></div><p>
 
617
The previous example's rendering has numerous deficiencies.  For one
 
618
thing, there are no lines connecting the various CDS rectangles in the
 
619
CDS track to show how they are organized into a spliced transcript.
 
620
For another, the repetition of the source tag "EMBL/GenBank/SwissProt"
 
621
is not particularly illuminating.
 
622
</p><p>
 
623
However, it's quite easy to customize the display, making the script
 
624
into a generally useful utility.  The revised code is shown in example
 
625
6.
 
626
</p><p>
 
627
<div class="example"><a id="code6"/><p class="title"><b>Example�6.�The embl2picture.pl script turns any EMBL or GenBank entry into a graphical rendering</b></p><pre class="programlisting">
 
628
  0  #!/usr/bin/perl
 
629
 
 
630
  1  # file: embl2picture.pl
 
631
  2  # This is code example 6 in the Graphics-HOWTO
 
632
  3  # Author: Lincoln Stein
 
633
 
 
634
  4  use strict;
 
635
  5  use lib "$ENV{HOME}/projects/bioperl-live";
 
636
  6  use Bio::Graphics;
 
637
  7  use Bio::SeqIO;
 
638
 
 
639
  8  use constant USAGE =&gt;&lt;&lt;END;
 
640
  9  Usage: $0 &lt;file&gt;
 
641
 10     Render a GenBank/EMBL entry into drawable form.
 
642
 11     Return as a GIF or PNG image on standard output.
 
643
 
 
644
 12     File must be in embl, genbank, or another SeqIO-
 
645
 13     recognized format.  Only the first entry will be 
 
646
 14     rendered.
 
647
 
 
648
 15  Example to try:
 
649
 16     embl2picture.pl factor7.embl | display -
 
650
 
 
651
 17  END
 
652
 
 
653
 18  my $file = shift                       or die USAGE;
 
654
 19  my $io = Bio::SeqIO-&gt;new(-file=&gt;$file) or die USAGE;
 
655
 20  my $seq = $io-&gt;next_seq                or die USAGE;
 
656
 21  my $wholeseq = Bio::SeqFeature::Generic-&gt;new(-start=&gt;1,-end=&gt;$seq-&gt;length,
 
657
 22                                               -display_name=&gt;$seq-&gt;display_name);
 
658
 
 
659
 23  my @features = $seq-&gt;all_SeqFeatures;
 
660
 
 
661
 24  # sort features by their primary tags
 
662
 25  my %sorted_features;
 
663
 26  for my $f (@features) {
 
664
 27    my $tag = $f-&gt;primary_tag;
 
665
 28    push @{$sorted_features{$tag}},$f;
 
666
 29  }
 
667
 
 
668
 30  my $panel = Bio::Graphics::Panel-&gt;new(
 
669
 31                                        -length    =&gt; $seq-&gt;length,
 
670
 32                                        -key_style =&gt; 'between',
 
671
 33                                        -width     =&gt; 800,
 
672
 34                                        -pad_left  =&gt; 10,
 
673
 35                                        -pad_right =&gt; 10,
 
674
 36                                        );
 
675
 37  $panel-&gt;add_track($wholeseq,
 
676
 38                    -glyph =&gt; 'arrow',
 
677
 39                    -bump =&gt; 0,
 
678
 40                    -double=&gt;1,
 
679
 41                    -tick =&gt; 2);
 
680
 
 
681
 42  $panel-&gt;add_track($wholeseq,
 
682
 43                    -glyph  =&gt; 'generic',
 
683
 44                    -bgcolor =&gt; 'blue',
 
684
 45                    -label  =&gt; 1,
 
685
 46                   );
 
686
 
 
687
 47  # special cases
 
688
 48  if ($sorted_features{CDS}) {
 
689
 49    $panel-&gt;add_track($sorted_features{CDS},
 
690
 50                      -glyph      =&gt; 'transcript2',
 
691
 51                      -bgcolor    =&gt; 'orange',
 
692
 52                      -fgcolor    =&gt; 'black',
 
693
 53                      -font2color =&gt; 'red',
 
694
 54                      -key        =&gt; 'CDS',
 
695
 55                      -bump       =&gt;  +1,
 
696
 56                      -height     =&gt;  12,
 
697
 57                      -label      =&gt; \&amp;gene_label,
 
698
 58                      -description=&gt; \&amp;gene_description,
 
699
 59                     );
 
700
 60    delete $sorted_features{'CDS'};
 
701
 61  }
 
702
 
 
703
 62  if ($sorted_features{tRNA}) {
 
704
 63    $panel-&gt;add_track($sorted_features{tRNA},
 
705
 64                      -glyph     =&gt;  'transcript2',
 
706
 65                      -bgcolor   =&gt;  'red',
 
707
 66                      -fgcolor   =&gt;  'black',
 
708
 67                      -font2color =&gt; 'red',
 
709
 68                      -key       =&gt; 'tRNAs',
 
710
 69                      -bump      =&gt;  +1,
 
711
 70                      -height    =&gt;  12,
 
712
 71                      -label     =&gt; \&amp;gene_label,
 
713
 72                     );
 
714
 73    delete $sorted_features{tRNA};
 
715
 74  }
 
716
 
 
717
 75  # general case
 
718
 76  my @colors = qw(cyan orange blue purple green chartreuse magenta yellow aqua);
 
719
 77  my $idx    = 0;
 
720
 78  for my $tag (sort keys %sorted_features) {
 
721
 79    my $features = $sorted_features{$tag};
 
722
 80    $panel-&gt;add_track($features,
 
723
 81                      -glyph    =&gt;  'generic',
 
724
 82                      -bgcolor  =&gt;  $colors[$idx++ % @colors],
 
725
 83                      -fgcolor  =&gt; 'black',
 
726
 84                      -font2color =&gt; 'red',
 
727
 85                      -key      =&gt; "${tag}s",
 
728
 86                      -bump     =&gt; +1,
 
729
 87                      -height   =&gt; 8,
 
730
 88                      -description =&gt; \&amp;generic_description
 
731
 89                     );
 
732
 90  }
 
733
 
 
734
 91  print $panel-&gt;png;
 
735
 92  exit 0;
 
736
 
 
737
 93  sub gene_label {
 
738
 94    my $feature = shift;
 
739
 95    my @notes;
 
740
 96    foreach (qw(product gene)) {
 
741
 97      next unless $feature-&gt;has_tag($_);
 
742
 98      @notes = $feature-&gt;each_tag_value($_);
 
743
 99      last;
 
744
100    }
 
745
101    $notes[0];
 
746
102  }
 
747
 
 
748
103  sub gene_description {
 
749
104    my $feature = shift;
 
750
105    my @notes;
 
751
106    foreach (qw(note)) {
 
752
107      next unless $feature-&gt;has_tag($_);
 
753
108      @notes = $feature-&gt;each_tag_value($_);
 
754
109      last;
 
755
110    }
 
756
111    return unless @notes;
 
757
112    substr($notes[0],30) = '...' if length $notes[0] &gt; 30;
 
758
113    $notes[0];
 
759
114  }
 
760
 
 
761
115  sub generic_description {
 
762
116    my $feature = shift;
 
763
117    my $description;
 
764
118    foreach ($feature-&gt;all_tags) {
 
765
119      my @values = $feature-&gt;each_tag_value($_);
 
766
120      $description .= $_ eq 'note' ? "@values" : "$_=@values; ";
 
767
121    }
 
768
122    $description =~ s/; $//; # get rid of last
 
769
123    $description;
 
770
124  }
 
771
</pre></div>
 
772
</p><p>
 
773
At 124 lines, this is the longest example in this HOWTO, but the
 
774
changes are straightforward.  The major difference occurs in lines
 
775
47-61 and 62-74, where we handle two special cases: "CDS" records and
 
776
"tRNAs".  For these two feature types we would like to draw the
 
777
features like genes using the "transcript2" glyph.  This glyph draws
 
778
inverted V's for introns, if there are any, and will turn the last (or
 
779
only) exon into an arrow to indicate the direction of transcription.
 
780
</p><p>
 
781
First we look to see whether there are any features with the primary
 
782
tag of "CDS" (lines 47-61).  If so, we create a track for them using
 
783
the desired glyph.  Line 49 shows how to add several features to a
 
784
track at creation time.  If the first argument to
 
785
<tt>add_track()</tt> is an array reference, all the
 
786
features contained in the array will be incorporated into the track.
 
787
We provide custom code references for the
 
788
<i><tt>-label</tt></i> and <i><tt>-description</tt></i>
 
789
options.  As we shall see later, the subroutines these code references
 
790
point to are responsible for extracting names and descriptions for the
 
791
coding regions.  After we handle this special case, we remove the CDS
 
792
feature type from the <tt>%sorted_features</tt> array.
 
793
</p><p>
 
794
We do the same thing for tRNA features, but with a different color
 
795
scheme (lines 62-74).
 
796
</p><p>
 
797
Having dealt with the special cases, we render the remaining feature
 
798
types using the same code we used earlier.  The only change is that
 
799
instead of allowing <tt>Bio::Graphics::Panel</tt> to
 
800
guess at the description from the feature's source tag, we use the
 
801
<tt>-description</tt> option to point to a subroutine
 
802
that will generate more informative description strings.
 
803
</p><p>
 
804
The <tt>gene_label()</tt> (lines 93-102) and
 
805
<tt>gene_description()</tt> (lines 103-114) subroutines
 
806
are simple.  The first one searches the feature for the tags "product"
 
807
and/or "gene" and uses the first one it finds as the label for the
 
808
feature.  The <tt>gene_description()</tt> subroutine is
 
809
similar, except that it returns the value of the first tag named
 
810
"note".  If the description is over 30 characters long, it is
 
811
truncated.
 
812
</p><p>
 
813
The <tt>generic_description()</tt> (lines 115-124) is
 
814
invoked to generate descriptions of all non-gene features.  We simply
 
815
concatenate together the names and values of tags.  For example the
 
816
entry:
 
817
<pre class="programlisting">
 
818
   source          1..12850
 
819
                   /db_xref="taxon:9606"
 
820
                   /organism="Homo sapiens"
 
821
                   /map="13q34"
 
822
</pre>
 
823
will be turned into the description string "db_xref=taxon:9606;
 
824
organism=Homo Sapiens; map=13q34".
 
825
</p><p>
 
826
After adding all the feature types, we call the panel's
 
827
<tt>png()</tt> method to generate a graphic file, which we
 
828
print to STDOUT.
 
829
</p><p>
 
830
Figure 6 shows an example of the output of this script.
 
831
</p><p>
 
832
<div class="figure"><a id="d3e238"/><div class="mediaobject"><img src="../figs/graphics/fig6.png"/></div><p class="title"><b>Figure�7.�The embl2picture.pl script</b></p></div>
 
833
</p></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a id="summary"/>9.�Summary</h2></div></div><p>
 
834
In summary, we have seen how to use the
 
835
<tt>Bio::Graphics</tt> module to generate
 
836
representations of sequence features as horizontal maps.  We applied
 
837
these techniques to two common problems: rendering the output of a
 
838
BLAST run, and rendering the feature table of a GenBank/EMBL entry.
 
839
</p><p>
 
840
The graphics module is quite flexible.  In addition to the options
 
841
that we have seen, there are glyphs for generating point-like features
 
842
such as SNPs, specialized glyphs that draw GC content and open reading
 
843
frames, and glyphs that generate histograms, bar charts and other
 
844
types of graphs.  <tt>Bio::Graphics</tt> has been used
 
845
to represent physical (clone) maps, radiation hybrid maps, EST
 
846
clusters, cytogenetic maps, restriction maps, and much more.
 
847
</p><p>
 
848
Although we haven't shown it, <tt>Bio::Graphics</tt>
 
849
provides support for generating HTML image maps.  The <a href="http://www.gmod.org" target="_top">Generic Genome Browser</a> uses this
 
850
facility to generate clickable, browsable images of the genome from a
 
851
variety of genome databases.
 
852
</p><p>
 
853
Another application you should investigate is the render_sequence.pl
 
854
script.  This script uses the BioFetch interface to fetch
 
855
GenBank/EMBL/SwissProt entries dynamically from the web before
 
856
rendering them into PNG images.
 
857
</p><p>
 
858
Finally, if you find yourself constantly tweaking the graphic options,
 
859
you might be interested in
 
860
<tt>Bio::Graphics::FeatureFile</tt>, a utility module
 
861
for interpreting and rendering a simple tab-delimited format for
 
862
sequence features.  feature_draw.PLS is a Perl script built on top of
 
863
this module, which you can find in the scripts/graphics directory in
 
864
the Bioperl distribution.
 
865
</p></div><div class="footnotes"><br/><hr width="100" align="left"/><div class="footnote"><p><sup>[<a id="ftn.d3e99" href="#d3e99">1</a>] </sup>Obtain the list of glyphs by running perldoc on
 
866
Bio::Graphics::Glyph.  Obtain a description of the glyph options by
 
867
running perldoc on individual glyphs, for example "perldoc Bio::Graphics::Glyph::arrow."
 
868
</p></div></div></div></body></html>
 
 
b'\\ No newline at end of file'