Bio-Graphics
view release on metacpan or search on metacpan
lib/Bio/Graphics/Glyph/wiggle_density.pm view on Meta::CPAN
# $scores is the numerator; $defined is the denominator
$scores += $val if defined $val;
$defined++ if defined $val;
# keep incrementing until we exceed 2 pixels
# the step is a fraction of a pixel, not an integer
$pixels += $pixelstep;
}
}
}
sub draw_plot {
my $self = shift;
my $parts = shift;
my ($gd,$dx,$dy) = @_;
my $x_scale = $self->scale;
my $panel_start = $self->panel->start;
my $feature = $self->feature;
my $f_start = $feature->start > $panel_start
? $feature->start
: $panel_start;
my ($left,$top,$right,$bottom) = $self->calculate_boundaries($dx,$dy);
# There is a minmax inherited from xyplot as well as wiggle_data, and I don't want to
# rely on Perl's multiple inheritance DFS to find the right one.
my ($min_score,$max_score,$mean,$stdev) = $self->minmax($parts);
my $rescale = $self->option('autoscale') eq 'z_score';
my ($scaled_min,$scaled_max);
if ($rescale) {
$scaled_min = int(($min_score-$mean)/$stdev + 0.5);
$scaled_max = int(($max_score-$mean)/$stdev + 0.5);
my $bound = $self->z_score_bound;
$scaled_max = $bound if $scaled_max > $bound;
$scaled_min = -$bound if $scaled_min < -$bound;
} else {
($scaled_min,$scaled_max) = ($min_score,$max_score);
}
my $pivot = $self->bicolor_pivot;
my $positive = $self->pos_color;
my $negative = $self->neg_color;
my $midpoint = $self->midpoint;
my ($rgb_pos,$rgb_neg,$rgb);
if ($pivot) {
$rgb_pos = [$self->panel->rgb($positive)];
$rgb_neg = [$self->panel->rgb($negative)];
} else {
$rgb = $scaled_max > $scaled_min ? ([$self->panel->rgb($positive)] || [$self->panel->rgb($self->bgcolor)])
: ([$self->panel->rgb($negative)] || [$self->panel->rgb($self->bgcolor)]);
}
my %color_cache;
my $flip = $self->{flip};
$self->panel->startGroup($gd);
foreach (@$parts) {
my ($start,$end,$score) = @$_;
next unless defined $score; # undefined (absent) score transparent
$score = ($score-$mean)/$stdev if $rescale;
$score = $scaled_min if $scaled_min > $score;
$score = $scaled_max if $scaled_max < $score;
my $x1 = $left + ($start - $f_start) * $x_scale;
my $x2 = $left + ($end - $f_start) * $x_scale;
if ($flip) {
$x1 = $right - ($x1-$left);
$x2 = $right - ($x2-$left);
($x1,$x2) = ($x2,$x1);
}
my ($r,$g,$b) = $pivot
? ($score > $midpoint ? $self->calculate_color($score,$rgb_pos,
$midpoint,$scaled_max)
: $self->calculate_color($score,$rgb_neg,
$midpoint,$scaled_min)
)
: $self->calculate_color($score,$rgb,
$scaled_min,$scaled_max);
my $idx = $color_cache{$r,$g,$b} ||= $self->panel->translate_color($r,$g,$b);
$self->filled_box($gd,$x1,$top,$x2,$bottom,$idx,$idx);
}
return 1;
}
sub _draw_coverage {
my $self = shift;
my $feature = shift;
my $array = shift;
$array = [split ',',$array] unless ref $array;
return unless @$array;
my ($start,$end) = $self->effective_bounds($feature);
my $bases_per_bin = ($end-$start)/@$array;
my $pixels_per_base = $self->scale;
my @parts;
for (my $pixel=0;$pixel<$self->width;$pixel++) {
my $offset = $pixel/$pixels_per_base;
my $s = $start + $offset;
my $e = $s+1; # fill in gaps
my $v = $array->[$offset/$bases_per_bin];
#$v = 0 unless defined $v; # don't want undefined values
push @parts,[$s,$s,$v];
}
$self->Bio::Graphics::Glyph::wiggle_density::draw_plot(\@parts,@_);
}
sub calculate_color {
my $self = shift;
my ($s,$rgb,$min_score,$max_score) = @_;
$s ||= $min_score;
return (255,255,255) unless $max_score - $min_score; # avoid div by zero
my $relative_score = ($s-$min_score)/($max_score-$min_score);
$relative_score = 0 if $relative_score < 0;
$relative_score = 1 if $relative_score > 1;
return map { int(255 - (255-$_) * $relative_score) } @$rgb;
( run in 1.778 second using v1.01-cache-2.11-cpan-39bf76dae61 )