Bio::Align Graphics
SummaryIncluded librariesPackage variablesSynopsisDescriptionGeneral documentationMethods
Toolbar
WebCvs
Summary
Bio::Align::Graphics - Graphic Rendering of Bio::Align::AlignI Objects
Package variables
No package variables defined.
Included modules
.008003
Bio::AlignIO
Data::Dumper
GD
GD::Simple
POSIX qw ( ceil floor )
strict
warnings
Inherit
Exporter
Synopsis
  use Bio::Align::Graphics;
#Get an AlignI object, usually by using Bio::AlignIO my $file=shift @ARGV; my $in=new Bio::AlignIO(-file=>$file, -format=>'clustalw'); my $aln=$in->next_aln(); #Create a new Graphics object my $print_align = new Bio::Align::Graphics(align => $aln); #Draw the alignment $print_align->draw();
Description
Bio::Align::Graphics is a module designed to create image files out of Bio::Align::AlignI objects. An alignment may be manipulated with various
formatting and highlighting options.
An example:
	#!/usr/bin/perl -w
use Bio::AlignIO; use Bio::Align::Graphics; use strict; #Get an alignment file my $file = shift @ARGV; #Create an AlignI object using AlignIO my $in=new Bio::AlignIO(-file=>$file, -format=>'clustalw'); #Read the alignment my $aln=$in->next_aln(); #Create some domains for highlighting my @domain_start = ( 25 , 50, 80 ); my @domain_end = ( 40 , 60 , 100 ); my @domain_color = ( 'red' , 'cyan' , 'green' ); #Create Labels for the domains my @dml = ("CARD", "Proline Rich", "Transmembrane"); my @dml_start = (25, 50, 80); my @dml_end = (40, 60, 100); my @dml_color = ("lightpink", "lightblue", "lightgreen"); #Create individual labels my %labels = ( 145 => "Hep-c target"); my $print_align = new Bio::Align::Graphics( align => $aln, pad_bottom => 5, domain_start => \@domain_start, domain_end => \@domain_end, dm_color => \@domain_color, dm_labels => \@dml, dm_label_start => \@dml_start, dm_label_end => \@dml_end, dm_label_color => \@dml_color, labels => \%labels, out_format => "png"); $print_align->draw();
Methods
new
No description
Code
draw
No description
Code
_draw_sequences
No description
Code
_domain_label
No description
Code
y_label
No description
Code
x_label
No description
Code
_draw_domain
No description
Code
_draw_colored_sequences
No description
Code
_draw_legend
No description
Code
width
No description
Code
height
No description
Code
aln_length
No description
Code
aln_format
No description
Code
no_sequences
No description
Code
Methods description
None available.
Methods code
newdescriptionprevnextTop
sub new {
my $class = shift;
my %options = @_;

my $self  = {
	
	#####OPTIONS#####
#Display Defaults
font => defined($options{font}) ? $FONT_TABLE{$options{font}} : $FONT_TABLE{2}, x_label => defined($options{x_label}) ? $options{x_label} : 1, y_label => defined($options{y_label}) ? $options{y_label} : 1, #Colors
bg_color => $options{bg_color} || 'white', fg_color => $options{font_color} || 'black', x_label_color => $options{x_label_color} || 'blue', y_label_color => $options{y_label_color} || 'red', p_color => $options{p_color} || undef, p_legend => $options{p_legend} || undef, p_color_table => undef, #Sequence Defaults
reference => $options{reference} || undef, reference_id => $options{reference_id} || undef, match_char => $options{match_char} || ".", block_size => defined($options{block_size}) ? $options{block_size} : 10, block_space => defined ($options{block_space}) ? ($options{block_space} * ($options{font} ? $FONT_TABLE{$options{font}}->width : $FONT_TABLE{2}->width)) : ( ($options{font} ? ($FONT_TABLE{$options{font}}->width * 2 ) : ($FONT_TABLE{2}->width * 2)) ), wrap => $options{wrap} || 80, show_nonsynonymous => $options{show_nonsynonymous} || undef, # If turned on, will highlight nonsynonymous (missense) mutations. Valid only for nucleotide alignments
#Padding
pad_left => $options{pad_left} || 5, #space between x label and border
pad_right => $options{pad_right} || 5, #space between end of sequences and border
pad_top => $options{pad_top} || 5, #space between y label and border
pad_bottom => $options{pad_bottom} || 5, #space between bottom of sequences and border
x_label_space => $options{x_label_space} || 1, #space between x label and sequences
y_label_space => $options{y_label_space} || 1, #space between y label and sequences
#Labels
labels => $options{labels} || undef, dm_labels => $options{dm_labels} || undef, dm_label_start => $options{dml_start} || undef, dm_label_end => $options{dml_end} || undef, dm_label_color => $options{dml_color} || undef, domain_start => $options{dm_start} || undef, domain_end => $options{dm_end} || undef, domain_color => $options{dm_color} || undef, #File Defaults
align => $options{align} || undef, output => $options{output} || undef, out_format => $options{out_format} || undef, ####PRIVATE VALUES#####
image => $options{image} || undef, seq_format => undef, #X and Y size of char
x_char_size => ($options{font} ? $FONT_TABLE{$options{font}}->width : $FONT_TABLE{2}->width), y_char_size => ($options{font} ? $FONT_TABLE{$options{font}}->height : $FONT_TABLE{2}->height), #Image W & H
width => undef, #overall width of the image
height => undef, #overall height of image
#Sequences
sequences => undef, seq_ids => undef, ref_sequence => undef, id_length => 0, seq_length => $options{align}->length() || 0, no_sequences => $options{align}->num_sequences() || 0, seq_start_x => undef, seq_start_y => undef, start => $options{start} || 1, end => $options{end} || $options{align}->length(), y_num => undef, y_size => undef, footer_size => 110, footer_start => undef }; bless ($self, $class); die "new:Must supply alignment for drawing!\n" unless defined ($self->{align}); foreach my $seq ($self->{align}->each_seq) { $self->{id_length} = ( length($seq->id()) > $self->{id_length} ) ? length($seq->id()) : $self->{id_length}; if( $self->{reference_id} && ($seq->id() eq $self->{reference_id}) ) { @{$self->{ref_sequence}} = split //, $seq->seq; unshift @{$self->{sequences}}, $seq->seq; unshift @{$self->{seq_ids}}, $seq->id(); }else { push @{$self->{sequences}}, $seq->seq; push @{$self->{seq_ids}}, $seq->id(); } if(!defined($self->{seq_format})) { $self->{seq_format} = $seq->alphabet; } } if(!($self->{reference_id}) ) { @{$self->{ref_sequence}} = split //, ${$self->{sequences}}[0]; $self->{reference_id} = ${$self->{seq_ids}}[0]; } $self->{y_num} = ($self->{seq_length} > $self->{wrap}) ? ( sprintf( "%.0f", ( ($self->{seq_length} / $self->{wrap}) + .5) ) ) : 1;
$self->{y_size} = ( ($self->{no_sequences} + $self->{pad_bottom}) * $self->{y_char_size}); $self->{seq_start_x} = ($self->{pad_left} + $self->{id_length} + $self->{x_label_space}) * $self->{x_char_size}; if( defined($self->{show_nonsynonymous}) ) # Extra column changes dimensions
{ $self->{seq_length_aa} = ($self->{seq_length} / 3) + $self->{seq_length}; # Consider length of sequence plus extra column every 3 nucleotides
$self->{seq_start_y} = ($self->{pad_top} + length($self->{seq_length_aa}) + $self->{y_label_space}) * $self->{y_char_size};
$self->{width} = $self->{seq_start_x} + ((( $self->{wrap} / $self->{block_size}) + 1) * $self->{block_space}) + ( ($self->{wrap} + $self->{pad_right}) * ($self->{x_char_size} + 1.2) ) + ( ($self->{seq_length} / 3) * 2); # Needed to add this for width to fit whole sequence on one line
}else { $self->{seq_start_y} = ($self->{pad_top} + length($self->{seq_length}) + $self->{y_label_space}) * $self->{y_char_size}; $self->{width} = $self->{seq_start_x} + ((( $self->{wrap} / $self->{block_size}) + 1) * $self->{block_space}) + ($self->{wrap} + $self->{pad_right}) * $self->{x_char_size};
} $self->{footer_start} = $self->{seq_start_y} + $self->{y_size} * $self->{y_num}; if(defined($self->{p_color}) && defined($self->{p_legend}) && $self->{p_legend}){ $self->{height} = $self->{seq_start_y} + $self->{footer_size} + $self->{y_size} * $self->{y_num}; }else{ $self->{height} = $self->{seq_start_y} + $self->{y_size} * $self->{y_num}; } $self->{image} = GD::Simple->new($self->{width},$self->{height}); $self->{image}->alphaBlending(1); $self->{image}->saveAlpha(1); $self->{image}->bgcolor($self->{bg_color}); $self->{image}->fgcolor($self->{fg_color}); $self->{image}->rectangle(0,0,$self->{width}-1, $self->{height} - 1); return $self; } #End new Subroutine#########################################################
}
drawdescriptionprevnextTop
sub draw {
my $self = shift;

die "draw:Must supply alignment for drawing!\n"
	unless defined ($self->{align});

if(defined($self->{x_label}) && $self->{x_label})
{
$self->x_label();
}

if(defined($self->{y_label}) && $self->{y_label})
{
$self->y_label();
}


if(defined($self->{domain_start}) && defined($self->{domain_end}) && not defined($self->{p_color}) )
{
$self->_draw_domain();
}

# 
if( defined($self->{show_nonsynonymous}) && ( $self->{seq_format} eq "protein" ) ) { die "draw:Option show_nonsynonymous only works with Nucleotide alignments!\n"; }elsif ( defined($self->{show_nonsynonymous}) ) { $self->{codon_table} = Bio::Tools::CodonTable->new(); $self->{missense_pos} = {}; # print STDERR "You are using option show_nonsynonymous. Option works best if wrap value is a multiple of 4.\n"
} if(defined($self->{p_color}) && $self->{seq_format} eq "protein") { $self->_draw_colored_sequences(); if(defined($self->{p_legend}) && $self->{p_legend}) { $self->_draw_legend(); } }elsif(defined($self->{p_color}) && ($self->{seq_format} ne "protein")) { die "draw:Option p_color only works with Protein alignments!\n"; }else { $self->_draw_sequences(); } if(defined($self->{dm_label_start})) { $self->_domain_label(); } if($self->{output}) { open(OUTPUT, ">$self->{output}"); binmode OUTPUT; if(defined($self->{out_format})) { SWITCH: { if($self->{out_format} eq "png") {print OUTPUT $self->{image}->png; last SWITCH;} if($self->{out_format} eq "jpeg") {print OUTPUT $self->{image}->jpeg; last SWITCH;} if($self->{out_format} eq "gif") {print OUTPUT $self->{image}->gif; last SWITCH;} if($self->{out_format} eq "gd") {print OUTPUT $self->{image}->gd; last SWITCH;} } }else { print OUTPUT $self->{image}->png; } close OUTPUT; }else { binmode STDOUT; if(defined($self->{out_format})) { SWITCH: { if($self->{out_format} eq "png") {print STDOUT $self->{image}->png; last SWITCH;} if($self->{out_format} eq "jpeg") {print STDOUT $self->{image}->jpeg; last SWITCH;} if($self->{out_format} eq "gif") {print STDOUT $self->{image}->gif; last SWITCH;} if($self->{out_format} eq "gd") {print STDOUT $self->{image}->gd; last SWITCH;} } }else { print STDOUT $self->{image}->png; } }#End Output if/else
#print "Left\tRight\tTop\tBottom\n";
#print $self->{pad_left}, "\t", $self->{pad_right}, "\t", $self->{pad_top}, "\t", $self->{pad_bottom}, "\n";
}; ##########################################
#Draws Sequences
}
_draw_sequencesdescriptionprevnextTop
sub _draw_sequences {
my $self = shift;

my $block_num = 0;
my $block_total = 0;
my $print_char;


$self->{image}->fgcolor($self->{fg_color});

for (my $i=0; $i < $self->{no_sequences}; $i++) 
{
	
	 my @letters = split //, ${$self->{sequences}}[$i];
	 
	   
	
	 my $y_num = $self->{y_num}; #sprintf( "%.0f", ( ($self->{seq_length} / $self->{wrap}) + .5) ) - 1;
my $y_char = $self->{y_size}; #( ($self->{no_sequences} + $self->{pad_bottom}) * $self->{y_char_size});
for(my $k=0; $k<=$y_num; $k++) { my $x_char = $k * $self->{wrap}; for (my $j=$x_char; $j <= ( ($x_char + $self->{wrap}) - 1); $j++) { last unless defined($letters[$j]); # If show_nonsynonymous is on, and this is the 3rd nucleotide,
# save the codon and amino acid for comparison
my ($codon, $aa); if ((defined($self->{show_nonsynonymous})) && ((($j+1) % 3) == 0)) { $codon = $letters[$j-2] . $letters[$j-1] . $letters[$j]; $aa = $self->{codon_table}->translate($codon); } if( $self->{reference} ) { if(${$self->{seq_ids}}[$i] eq $self->{reference_id}) { $print_char = $letters[$j]; }else { if($letters[$j] eq ${$self->{ref_sequence}}[$j]) { $print_char = $self->{match_char}; }else { $print_char = $letters[$j]; } } }else { $print_char = $letters[$j]; } if( ( ($j + 1) % ($self->{block_size})) == 0) { $block_num = $self->{block_space}; }else { $block_num = 0; } #print "J is: $j\n";
#print "Char is: $print_char\n";
my $new_x_pos = $self->{seq_start_x} + ( ($j - $x_char) * $self->{x_char_size}) + $block_total; my $new_y_pos = $self->{seq_start_y} + ($i * $self->{y_char_size}) + ($k * $y_char); $new_x_pos += ( ( floor( ($j-$x_char)/3 ) * $self->{x_char_size} ) +
( ( floor( (
$j-$x_char)/3 ) ) * 6 )) if ( defined($self->{show_nonsynonymous}) ); $self->{image}->moveTo( $new_x_pos, $new_y_pos ); $self->{image}->font($self->{font}); $self->{image}->string($print_char); if ( (defined($self->{show_nonsynonymous})) && ((($j+1) % 3) == 0) ) { $new_x_pos += ($self->{x_char_size} + 3); $self->{image}->moveTo( $new_x_pos, $new_y_pos ); # If show_nonsynonymous is on, and this is the 3rd nucleotide
# on reference, print the amino acid after the nucleotide
if(($self->{reference}) && (${$self->{seq_ids}}[$i] eq $self->{reference_id})) { $self->{image}->font(gdMediumBoldFont); $self->{image}->string($aa); $self->{image}->font($self->{font}); }elsif ( ( $self->{reference} ) && ( ${$self->{seq_ids}}[$i] ne $self->{reference_id} ) ) { # In case current sequence is not reference
my $ref_codon = ${$self->{ref_sequence}}[$j-2] . ${$self->{ref_sequence}}[$j-1] . ${$self->{ref_sequence}}[$j]; my $ref_aa = $self->{codon_table}->translate($ref_codon); if ( $ref_aa eq $aa ) # Synonymous mutation
{ $self->{image}->string($self->{match_char}); }else # Nonsynonymous mutation
{ $self->{image}->font(gdMediumBoldFont); $self->{image}->string($aa); $self->{image}->font($self->{font}); # Highlight nonsynonymous mutations by drawing a rectangle around them
if ( ( ${$self->{seq_ids}}[$i] ne $self->{reference_id} ) && !( ${$self->{missense_pos}}{$j} ) ) { ${$self->{missense_pos}}{$j} = 1; $self->{image}->bgcolor(undef); $self->{image}->rectangle( $new_x_pos - 2, ( $new_y_pos - ( ( $self->{y_char_size} * ($i+1)) ) ) - 2, ( $new_x_pos + ( $self->{x_char_size} + 1) ), ( $new_y_pos + ( $self->{y_char_size} * ( $self->{no_sequences} - ( $i+1 ) ) ) ) + 2); $self->{image}->bgcolor($self->{bg_color}); } } }else # No reference sequence defined
{ $self->{image}->string($aa); } } if( defined($self->{labels}) && $i == ($self->{no_sequences} - 1)) { if(${$self->{labels}}{$j + 1}) { my $label = ${$self->{labels}}{$j + 1}; my $offset = defined($self->{dm_label_start}) ? 3 : 0; $self->{image}->moveTo($self->{seq_start_x} + ( ( ($j - $x_char) + 1.25) * $self->{x_char_size}) + $block_total, $self->{seq_start_y} + (($self->{no_sequences}) * $self->{y_char_size}) + ($k * $y_char) + ( (length($label) + $offset) * ($self->{x_char_size}) ) ); $self->{image}->font($self->{font}); $self->{image}->angle(-90); $self->{image}->string($label); $self->{image}->angle(0); } } $block_total += $block_num; } $block_total = 0; } } } # WARNING YH - This function has not been modified to work with show_nonsynonymous: needs test data to make sure it will work!
##############################################
#Draw Domain Label
}
_domain_labeldescriptionprevnextTop
sub _domain_label {
my $self = shift;
my $start_block_total = 0;
my $end_block_total = 0;
my $wrap_block_total = 0;

my $y_char = $self->{y_size};# ( ($self->{no_sequences} + $self->{pad_bottom}) * $self->{y_char_size});
for(my $i = 0; $i <= $#{$self->{dm_label_start}}; $i++) { my $start = ${$self->{dm_label_start}}[$i]; my $end = ${$self->{dm_label_end}}[$i]; my $y_num_start = int( $start / $self->{wrap});
my $y_num_end = int( $end / $self->{wrap});
my $x_num_start; if($start >= $self->{wrap}) { $x_num_start = ($start % $self->{wrap}) - 1; }else { $x_num_start = $start - 1; } my $x_num_end; if($end >= $self->{wrap}) { $x_num_end = ($end % $self->{wrap}); }else { $x_num_end = $end; } my $label = ${$self->{dm_labels}}[$i]; my $color = ${$self->{dm_label_color}}[$i] || ${$self->{dm_label_color}}[-1] || "silver"; my $label_x = (($x_num_end - $x_num_start) / 2) - (length($label) / 2); my $label_x_start = (($self->{wrap} - $x_num_start) / 2) - (length($label) / 2); my $label_x_end = ($x_num_end / 2) - (length($label) / 2); $start_block_total = ( ($x_num_start - ($x_num_start % $self->{block_size}) ) / $self->{block_size} ) * $self->{block_space};
$end_block_total = ( ($x_num_end - ($x_num_end % $self->{block_size}) ) / $self->{block_size} ) * $self->{block_space};
$wrap_block_total = ( ($self->{wrap} - ( ($self->{wrap} - 1) % $self->{block_size}) ) / $self->{block_size} ) * $self->{block_space};
$self->{image}->bgcolor($color); $self->{image}->fgcolor($color); if($y_num_start == $y_num_end) #if the label does not cross the wrap line
{ $self->{image}->rectangle( $self->{seq_start_x} + ( ($x_num_start) * $self->{x_char_size} ) + $start_block_total, $self->{seq_start_y} + (($self->{no_sequences}) * $self->{y_char_size}) + ($y_num_start * $y_char), $self->{seq_start_x} + (($x_num_end) * $self->{x_char_size}) + $end_block_total, $self->{seq_start_y} + (($self->{no_sequences} + 1) * $self->{y_char_size}) + ($y_num_start * $y_char)); $self->{image}->fgcolor($self->{fg_color}); $self->{image}->bgcolor($self->{bg_color}); $self->{image}->moveTo( $self->{seq_start_x} + ( ($x_num_start + $label_x) * $self->{x_char_size}) + $start_block_total, $self->{seq_start_y} + (($self->{no_sequences} + 1) * $self->{y_char_size}) + ($y_num_start * $y_char) ); $self->{image}->font($self->{font}); $self->{image}->string($label); }else { $self->{image}->rectangle( $self->{seq_start_x} + ( ($x_num_start) * $self->{x_char_size} ) + $start_block_total, $self->{seq_start_y} + (($self->{no_sequences}) * $self->{y_char_size}) + ($y_num_start * $y_char), $self->{seq_start_x} + (($self->{wrap}) * $self->{x_char_size}) + $wrap_block_total, $self->{seq_start_y} + (($self->{no_sequences} + 1) * $self->{y_char_size}) + ($y_num_start * $y_char)); $self->{image}->rectangle( $self->{seq_start_x} , $self->{seq_start_y} + (($self->{no_sequences}) * $self->{y_char_size}) + ($y_num_end * $y_char), $self->{seq_start_x} + (($x_num_end) * $self->{x_char_size}) + $end_block_total, $self->{seq_start_y} + (($self->{no_sequences} + 1) * $self->{y_char_size}) + ($y_num_end * $y_char)); $self->{image}->fgcolor($self->{fg_color}); $self->{image}->bgcolor($self->{bg_color}); $self->{image}->moveTo( $self->{seq_start_x} + ( ($x_num_start + $label_x_start) * $self->{x_char_size}) + $start_block_total, $self->{seq_start_y} + (($self->{no_sequences} + 1) * $self->{y_char_size}) + ($y_num_start * $y_char) ); $self->{image}->font($self->{font}); $self->{image}->string($label); $self->{image}->moveTo( $self->{seq_start_x} + ( $label_x_end * $self->{x_char_size}), $self->{seq_start_y} + (($self->{no_sequences} + 1) * $self->{y_char_size}) + ($y_num_end * $y_char) ); $self->{image}->font($self->{font}); $self->{image}->string($label); } } } ##############################################
#Draw Y Label
}
y_labeldescriptionprevnextTop
sub y_label {
my $self = shift;

$self->{image}->fgcolor($self->{y_label_color});

	my $y_num = $self->{y_num}; #sprintf( "%.0f" , (($self->{seq_length} / $self->{wrap}) + .5)) - 1;
my $y_char = $self->{y_size}; # ( ($self->{no_sequences} + $self->{pad_bottom}) * $self->{y_char_size});
for(my $k=0; $k<$y_num; $k++) { for (my $i=0; $i< $self->{no_sequences}; $i++) { $self->{image}->moveTo($self->{pad_left}, $self->{seq_start_y} + ($i * $self->{y_char_size}) + ($k * $y_char) ); $self->{image}->font($self->{font}); $self->{image}->string(${$self->{seq_ids}}[$i]); } } } #####################################################
#Draw X Label
}
x_labeldescriptionprevnextTop
sub x_label {
my $self = shift;

my $block_num = 0;
my $block_total = 0;
$self->{image}->fgcolor($self->{x_label_color});

my $y_char = $self->{y_size}; # ( ($self->{no_sequences} + $self->{pad_bottom}) * $self->{y_char_size});
for (my $i=1; $i<= $self->{seq_length}; $i++) { my $y_num = floor( $i / $self->{wrap}); # Used to be int(), but perl documentation advises against this
my
$x_num;
if($i >= $self->{wrap}) { $x_num = ($i % $self->{wrap}); }else { $x_num = $i; } my @digits = split //, reverse($i); if( ($i % $self->{block_size}) == 0) { $block_num = $self->{block_space}; }else { $block_num = 0; } if( (($i - 1) % $self->{block_size}) == 0) { for (my $j=0; $j<=$#digits; $j++) { if ( defined($self->{show_nonsynonymous}) ) { $self->{image}->moveTo($self->{seq_start_x} + $block_total + ( ($x_num-1) * $self->{x_char_size}) + ( ( floor( ($x_num-1)/3 ) * $self->{x_char_size} ) + ( ( floor( ($x_num-1)/3 ) ) * 6 )), ($self->{pad_top} + length($self->{seq_length_aa}) - $j) * $self->{y_char_size} + ($y_num * $y_char)); }else { $self->{image}->moveTo($self->{seq_start_x} + $block_total + ( ($x_num-1) * $self->{x_char_size}), ($self->{pad_top} + length($self->{seq_length}) - $j) * $self->{y_char_size} + ($y_num * $y_char)); } $self->{image}->font($self->{font}); $self->{image}->string($digits[$j]); } } if($x_num == 0) { $block_total = 0; }else { $block_total += $block_num; } } } ####################################################
#Domain Highlighting
}
_draw_domaindescriptionprevnextTop
sub _draw_domain {
my $self = shift;


my $block_total = 0;
my ($start, $end, $block_num);


my $y_char = $self->{y_size}; # ( ($self->{no_sequences} + $self->{pad_bottom}) * $self->{y_char_size});
for (my $k=0; $k <= $#{$self->{domain_start}}; $k++) { #print STDERR join "\n", GD::Simple->color_names;
my $dmc = $self->{domain_color}[$k] || $self->{domain_color}[-1] || "silver"; $start = ${$self->{domain_start}}[$k] - 1; $end = ${$self->{domain_end}}[$k] - 1; for (my $i=0; $i < $self->{no_sequences}; $i++) { for (my $j = $start; $j <= $end; $j++) { my $y_num = int( $j / $self->{wrap});
my $x_num; if($j >= $self->{wrap}) { $x_num = ($j % $self->{wrap}); }else { $x_num = $j; } #print "J: $j\nXNUM: $x_num\nYNUM: $y_num\n";
$block_total = ( ($x_num - ($x_num % $self->{block_size}) ) / $self->{block_size} ) * $self->{block_space};
$self->{image}->bgcolor($dmc); $self->{image}->fgcolor($dmc); if ( defined($self->{show_nonsynonymous}) ) { # NOTE To shade amino acids as well, change $x_num HERE and HERE to $x_num + 1
$self->{image}->rectangle( $self->{seq_start_x} + ( ($x_num ) * $self->{x_char_size} ) + $block_total - 1 + ( ( floor( $x_num / 3 ) * $self->{x_char_size} ) + ( ( floor( $x_num / 3 ) ) * 6 )), $self->{seq_start_y} + ( $i * $self->{y_char_size} ) - $self->{y_char_size} + ($y_num * $y_char) , $self->{seq_start_x} + (($x_num + 1) * $self->{x_char_size}) + $block_total - 1 + ( ( floor( ($x_num)/3 ) * $self->{x_char_size} ) + ( ( floor( ($x_num)/3 ) ) * 6 )), $self->{seq_start_y} + ( $i * $self->{y_char_size}) + ($y_num * $y_char)); }else { $self->{image}->rectangle( $self->{seq_start_x} + ( ($x_num ) * $self->{x_char_size} ) + $block_total - 1, $self->{seq_start_y} + ( $i * $self->{y_char_size} ) - $self->{y_char_size} + ($y_num * $y_char) , $self->{seq_start_x} + (($x_num + 1) * $self->{x_char_size}) + $block_total - 1, $self->{seq_start_y} + ( $i * $self->{y_char_size}) + ($y_num * $y_char)); } #$self->{image}->rectangle( $self->{seq_start_x} + ( ($j) * $self->{x_char_size} ) + $block_total, $self->{seq_start_y} + ($i - 1 * $self->{y_char_size}), $self->{seq_start_x} + (($j + 1) * $self->{x_char_size}) + $block_total , $self->{seq_start_y} + ( ($i) * $self->{y_char_size}));
$self->{image}->fgcolor($self->{fg_color}); $self->{image}->bgcolor($self->{bg_color}); } $block_total = 0; } }
}
_draw_colored_sequencesdescriptionprevnextTop
sub _draw_colored_sequences {
my $self = shift;

my $block_num = 0;
my $block_total = 0;
my $print_char;
my %colors;

for my $values ( keys %PROTEIN_COLORS)
{
#print STDERR "$values : @{ $PROTEIN_COLORS{$values} }\n";
$colors{$values} = $self->{image}->colorAllocate(@{ $PROTEIN_COLORS{$values} }); } $self->{p_color_table} =\% colors; $self->{image}->fgcolor($self->{fg_color}); for (my $i=0; $i < $self->{no_sequences}; $i++) { my @letters = split //, ${$self->{sequences}}[$i]; my $y_num = $self->{y_num}; #sprintf( "%.0f", ( ($self->{seq_length} / $self->{wrap}) + .5) ) - 1;
my $y_char = $self->{y_size}; #( ($self->{no_sequences} + $self->{pad_bottom}) * $self->{y_char_size});
for(my $k=0; $k<=$y_num; $k++) { my $x_char = $k * $self->{wrap}; for (my $j=$x_char; $j <= ( ($x_char + $self->{wrap}) - 1); $j++) { last unless defined($letters[$j]); $print_char = $letters[$j]; if( ( ($j + 1) % ($self->{block_size})) == 0) { $block_num = $self->{block_space}; }else { $block_num = 0; } #print "Chunk Space: $chunk_space\n";
$self->{image}->bgcolor($colors{$print_char}); $self->{image}->fgcolor($colors{$print_char}); $self->{image}->rectangle( $self->{seq_start_x} + ( ($j - $x_char) * $self->{x_char_size} ) + $block_total - 1 , $self->{seq_start_y} + ( $i * $self->{y_char_size} ) + ($k * $y_char) - $self->{y_char_size} , $self->{seq_start_x} + (($j - $x_char + 1) * $self->{x_char_size}) + $block_total - 1 , $self->{seq_start_y} + ($k * $y_char) + ( $i * $self->{y_char_size})); $self->{image}->moveTo($self->{seq_start_x} + ( ($j - $x_char) * $self->{x_char_size}) + $block_total, $self->{seq_start_y} + ($k * $y_char) + ($i * $self->{y_char_size}) ); $self->{image}->fgcolor($self->{fg_color}); $self->{image}->font($self->{font}); $self->{image}->string($print_char); if( defined($self->{labels}) && $i == ($self->{no_sequences} - 1)) { if(${$self->{labels}}{$j + 1}) { my $label = ${$self->{labels}}{$j + 1}; my $offset = defined($self->{dm_label_start}) ? 3 : 0; $self->{image}->moveTo($self->{seq_start_x} + ( ( ($j - $x_char) + 1.25) * $self->{x_char_size}) + $block_total, $self->{seq_start_y} + (($self->{no_sequences}) * $self->{y_char_size}) + ($k * $y_char) + ( (length($label) + $offset) * ($self->{x_char_size}) ) ); $self->{image}->font($self->{font}); $self->{image}->angle(-90); $self->{image}->string($label); $self->{image}->angle(0); } } $block_total += $block_num; } $block_total = 0; } }
}
_draw_legenddescriptionprevnextTop
sub _draw_legend {
my $self = shift;
my $title_font = $FONT_TABLE{3};
my @l_order = ("Negatively Charged", "Positively Charged", "Hydrophobic", "Aromatic", "Found in Loops", "Large Polar Acids");
my %legend = ("Negatively Charged" => ["D" , "E"] , "Positively Charged" => ["K", "R"] , "Hydrophobic" => ["A","F","I","L","M","V","W","Y"] ,
		"Aromatic" => ["F", "H", "W", "Y"] , "Found in Loops" => ["D", "G", "P", "S", "T"] , "Large Polar Acids" => ["H", "K", "N", "Q", "R"]);

my $x1 = 2;
my $x2 = 42;

my $colors = $self->{p_color_table};

my $y_start = $self->{footer_start};
my $label = "Protein Color Legend";
$self->{image}->bgcolor($self->{bg_color});
$self->{image}->fgcolor($self->{fg_color});
$self->{image}->rectangle(1,$y_start, 70 * $self->{x_char_size}, $self->{height} - 2);

$self->{image}->moveTo((35 - (length($label) / 2) ) * $self->{x_char_size} , $y_start + $self->{y_char_size});
$self->{image}->font($title_font); $self->{image}->string($label); my $count = 3; foreach my $c_label (@l_order) { if( ($count % 2) == 0) { $self->{image}->moveTo( $x2 * $self->{x_char_size}, $y_start + ( ($count - 1) * $self->{y_char_size})); $self->{image}->font($self->{font}); $self->{image}->string($c_label); my $i = 0; foreach my $chars(@{$legend{$c_label}}) { $self->{image}->bgcolor($$colors{$chars}); $self->{image}->fgcolor($$colors{$chars}); $self->{image}->rectangle( ($x2 + 20 + $i) * $self->{x_char_size}, $y_start + ( ($count - 2) * $self->{y_char_size}), ($x2 + 20 + $i + 1) * $self->{x_char_size}, $y_start + ( ($count -1) * $self->{y_char_size})); $self->{image}->bgcolor($self->{bg_color}); $self->{image}->fgcolor($self->{fg_color}); $i++; } }else { $self->{image}->moveTo($x1 * $self->{x_char_size} , $y_start + ($count * $self->{y_char_size})); $self->{image}->font($self->{font}); $self->{image}->string($c_label); my $i = 0; foreach my $chars(@{$legend{$c_label}}) { $self->{image}->bgcolor($$colors{$chars}); $self->{image}->fgcolor($$colors{$chars}); $self->{image}->rectangle( ($x1 + 20 + $i) * $self->{x_char_size}, $y_start + ( ($count - 1) * $self->{y_char_size}), ($x1 + 20 + $i + 1) * $self->{x_char_size}, $y_start + ( ($count) * $self->{y_char_size})); $self->{image}->bgcolor($self->{bg_color}); $self->{image}->fgcolor($self->{fg_color}); $i++; } } $count += 1; } } ########################################
#####ACCESSORS#####
}
widthdescriptionprevnextTop
sub width {
my $self = shift;
return $self->{image}->width if exists $self->{image};
}
heightdescriptionprevnextTop
sub height {
my $self = shift;
return $self->{image}->height if exists $self->{image};
}
aln_lengthdescriptionprevnextTop
sub aln_length {
my $self = shift;
return $self->{seq_length} if exists $self->{seq_length};
}
aln_formatdescriptionprevnextTop
sub aln_format {
my $self = shift;
return $self->{seq_format} if exists $self->{seq_format};
}
no_sequencesdescriptionprevnextTop
sub no_sequences {
my $self = shift;
return $self->{no_sequences} if exists $self->{no_sequences};
}

1;
__END__
}
General documentation
CONSTRUCTORSTop
new() is the constructor for Bio::Align::Graphics:
    $print_align = Bio::Align::Graphics->new(@options)
    The new() method creates a new graphics object. The options are
a set of tag/value pairs as follows:
  Option         Value                                  Default
------ ----- -------
align Bio::AlignI object None, must be supplied to draw an alignment output Filename to print image to STDOUT out_format png, jpeg, gif, gd png font Size of font, ranging from 1 to 5 2 and equal to the standard GD fonts ranging from gdTinyFont to gdGiantFont x_label Draws a scale numbering alignment true bases along top of image, every x bases are numbered, where x is the block_size option y_label Draws sequence ids of alignment true along left side of image bg_color Background color of the image white font_color Color of the font used for drawing black the alignment characters x_label_color Color of the font used for drawing red the base scale characters y_label_color Color of the font used for drawing blue the sequence id characters p_color Colors protein bases according to false a coloring scheme proposed by W.R. Taylor(Protein Engineering, vol 10 no 7, 1997), only works with protein alignments pad_top Additional whitespace characters 5 between top of image and x-label pad_bottom Additional whitespace characters 5 between bottom of image and alignment pad_left Additional whitespace characters 5 between left side of image and y-label pad_right Additional whitespace characters 5 between right side of image and alignment x_label_space Additional whitespace characters 1 between x_label and alignment y_label_space Additional whitespace characters 1 between y_label and alignment reference Characters which are identical to false the reference sequence are replaced with the match character reference_id Sequence id of the sequence to use First sequence as the reference supplied in alignment match_char Character to replace identical bases . in aligned sequences block_size Number of bases to group together 10 when printing alignment, groups are separated by whitespace block_space Amount of character whitespace to 2 separate groups of bases by labels A hash containing labels to be none printed beneath the alignment, where the keys are the bases to print the values at dm_start An array containing start bases none for highlighting of segments of the alignment, paired with dm_end option dm_end An array containing end bases none for highlighting of segments of the alignment, paired with dm_start options dm_color An array containing colors for silver highlighting segments of bases denoted by the coordinates located in the dm_start and dm_end options dml_start An array containing start bases none for addition of domain labels underneath the alignment, paired with dml_end dml_end An array containing end bases none for addition of domain labels underneath the alignment, paired with dml_start dml_color An array containing colors for silver the domain labels denoted by the coordinates located in the dml_start and dml_end options dm_labels An array containing labels to be none printed underneath specified domains, each label should correspond with the base position located in the dml_start option show_nonsynonymous Boolean value to turn option false on or off. If 0 (or undef), option is off. If 1 (or non-0), option is on. Only valid for nucleotide alignments. Output images are wider with this option on.
    Note that all arrays and hashes must be passed by reference.
OBJECT METHODSTop
    $draw_align->draw();
    The draw() method draws the image with the options that were specified with new().
    $draw_align->width();
    Get the width of the image created with new(), in pixels.
    $draw_align->height();
    Get the height of the image created with new(), in pixels.
    $draw_align->aln_length();
    Get the length of the alignment submitted to new().
    $draw_align->aln_format();
    Get the format of the alignment submitted to new().
    $draw_align->no_sequences();
    Get the number of sequences in the alignment submitted to new().
AUTHORS AND CONTRIBUTORSTop
William McCaig, <wmccaig@gmail.com>
Mikhail Bekarev, <mbekarev@hunter.cuny.edu>
Yözen Hernández, <yzhernand@gmail.com>
Weigang Qiu (Corresponding Developer), <weigang@genectr.hunter.cuny.edu>
COPYRIGHT AND LICENSETop
Copyright (C) 2006-2008 by William McCaig
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.3 or,
at your option, any later version of Perl 5 you may have available.
SEE ALSOTop
Bio::Align::AlignI,
Bio::AlignIO,
GD,
GD::Simple