ANSI-Heatmap
view release on metacpan or search on metacpan
=head1 DESCRIPTION
Produce cutting-edge ANSI heatmaps using 256 colours and weird Unicode
characters! Perfect for 3D (2D + intensity) data.
=head1 METHODS
=head2 new ( [ARGS] )
C<ARGS> may be a hash or hashref accepting the following keys, which
also have getter/setter methods:
=over 4
=item min_x, max_x ( INT )
Specify the smallest and largest X-axis value to include. If not
provided, defaults to the smallest/largest values passed to C<set>
or C<inc>. Can be used to crop the map or ensure it keeps a fixed
size even if some values are unset.
To make automatic again, set to C<undef>.
=item min_y, max_y ( INT )
Ditto for the Y-axis.
=item min_z, max_z ( FLOAT )
Ditto for intensity; useful for keeping a fixed intensity across
multiple heatmaps.
=item width, height ( INT )
Specify the width/height of the map in characters. Defaults to
using the min_I<axis> and max_I<axis> values to determine the
width/height.
=item interpolate ( BOOL )
If width/height is not a nice multiple of the input data and
this flag is set, perform bilinear interpolation (instead of
nearest neighbour). This is a trade off; interpolated data is
blurrier, but retains a linear relationship with the original
data. Off by default.
=back
=head2 set ( X, Y, Z )
Set the heatmap intensity for the given X and Y co-ordinate.
Currently, only integer values for X and Y are supported.
=head2 get ( X, Y )
Return the heatmap intensity for the given X and Y co-ordinate,
or 0 if unset.
=head2 inc ( X, Y )
Increase the intensity at the given co-ordinate by 1.
=head2 to_string
Return a string containing the ANSI heatmap. If C<half> is set,
this string contains wide characters, so you may need to:
binmode STDOUT, ':utf8';
or
use open OUT => ':utf8';
before printing anything (in this case) to STDOUT.
examples/boxes.pl view on Meta::CPAN
max_x => $x,
max_y => $y,
swatch => 'grayscale',
);
my @white = (
(map { [1,$_], [$x,$_] } (1..$y)),
(map { [$_, 1], [$_, $y] } (1..$x)),
);
for my $c (@white) {
$map->set(@$c, 100);
}
print "$x x $y\n";
print $map, "\n";
}
}
examples/gray.pl view on Meta::CPAN
my $map = ANSI::Heatmap->new(
half => 1,
min_x => 1,
min_y => 1,
max_x => 10,
max_y => 10,
swatch => 'grayscale',
);
for my $x (1..10) {
for my $y (1..10) {
$map->set($x, $y, $x * $y);
}
}
print $map->to_string; # explicit
examples/interp.pl view on Meta::CPAN
use ANSI::Heatmap;
binmode STDOUT, ':utf8';
my $map = ANSI::Heatmap->new(
half => 1,
swatch => 'grayscale',
);
for my $x (0..5) {
for my $y (0..5) {
$map->set($x, $y, ($x % 2 == $y % 2));
}
}
for my $wh ([3,3], [3,5], [5,5], [6,6], [12,12], [15,16], [10,20]) {
my ($w, $h) = @$wh;
$map->width($w);
$map->height($h);
$map->interpolate(0);
print "${w}x${h}\n";
print $map;
examples/smallinterp.pl view on Meta::CPAN
binmode STDOUT, ':utf8';
my $map = ANSI::Heatmap->new(
half => 1,
swatch => 'grayscale',
);
for my $x (0..19) {
for my $y (0..19) {
my $sc = 1 + ($x >= 10) + ($y >= 10) * 2;
my $z = (($x/$sc) % 2 == ($y/$sc) % 2);
$map->set($x, $y, $z);
}
}
print "$map\n";
$map->width(15);
$map->height(15);
print "$map\n";
$map->interpolate(1);
print "$map\n";
lib/ANSI/Heatmap.pm view on Meta::CPAN
croak "Invalid constructor argument(s) " . join(', ', sort keys %args);
}
return $self;
}
sub swatch_names {
my $self = shift;
return (sort keys %SWATCHES);
}
sub set {
my ($self, $x, $y, $z) = @_;
$self->{map}[$y][$x] = $z;
$self->_set_minmax(x => $x, y => $y, z => $z);
}
sub get {
my ($self, $x, $y) = @_;
return $self->{map}[$y][$x] || 0;
}
sub inc {
my ($self, $x, $y) = @_;
$self->set( $x, $y, $self->get($x, $y) + 1 );
}
sub swatch {
my $self = shift;
if (@_) {
my $sw = shift;
@_ == 0 or croak "swatch: excess arguments";
if (ref $sw) {
ref $sw eq 'ARRAY' or croak "swatch: invalid argument, should be string or arrayref";
@$sw > 0 or croak "swatch: swatch is empty";
lib/ANSI/Heatmap.pm view on Meta::CPAN
my ($fy, $by) = modf($y);
my @p = map { $get->($bx + $_->[0], $by + $_->[1]) } ([0,0],[0,1],[1,0],[1,1]);
my $y1 = $p[0] + ($p[1] - $p[0]) * $fy;
my $y2 = $p[2] + ($p[3] - $p[2]) * $fy;
my $z = $y1 + ($y2 - $y1) * $fx;
return $z;
};
}
sub _set_minmax {
my ($self, %vals) = @_;
my $mm = $self->{minmax};
while (my ($k, $v) = each %vals) {
if (!defined $mm->{"min_$k"}) {
$mm->{"min_$k"} = $mm->{"max_$k"} = $v;
}
else {
$mm->{"min_$k"} = min($mm->{"min_$k"}, $v);
$mm->{"max_$k"} = max($mm->{"max_$k"}, $v);
}
lib/ANSI/Heatmap.pm view on Meta::CPAN
=head1 DESCRIPTION
Produce cutting-edge ANSI heatmaps using 256 colours and weird Unicode
characters! Perfect for 3D (2D + intensity) data.
=head1 METHODS
=head2 new ( [ARGS] )
C<ARGS> may be a hash or hashref accepting the following keys, which
also have getter/setter methods:
=over 4
=item min_x, max_x ( INT )
Specify the smallest and largest X-axis value to include. If not
provided, defaults to the smallest/largest values passed to C<set>
or C<inc>. Can be used to crop the map or ensure it keeps a fixed
size even if some values are unset.
To make automatic again, set to C<undef>.
=item min_y, max_y ( INT )
Ditto for the Y-axis.
=item min_z, max_z ( FLOAT )
Ditto for intensity; useful for keeping a fixed intensity across
multiple heatmaps.
lib/ANSI/Heatmap.pm view on Meta::CPAN
=item width, height ( INT )
Specify the width/height of the map in characters. Defaults to
using the min_I<axis> and max_I<axis> values to determine the
width/height.
=item interpolate ( BOOL )
If width/height is not a nice multiple of the input data and
this flag is set, perform bilinear interpolation (instead of
nearest neighbour). This is a trade off; interpolated data is
blurrier, but retains a linear relationship with the original
data. Off by default.
=back
=head2 set ( X, Y, Z )
Set the heatmap intensity for the given X and Y co-ordinate.
Currently, only integer values for X and Y are supported.
=head2 get ( X, Y )
Return the heatmap intensity for the given X and Y co-ordinate,
or 0 if unset.
=head2 inc ( X, Y )
Increase the intensity at the given co-ordinate by 1.
=head2 to_string
Return a string containing the ANSI heatmap. If C<half> is set,
this string contains wide characters, so you may need to:
binmode STDOUT, ':utf8';
or
use open OUT => ':utf8';
before printing anything (in this case) to STDOUT.
use Test::More tests => 16;
use strict;
use warnings;
use ANSI::Heatmap;
my $map = ANSI::Heatmap->new;
$map->set(0,0,1);
$map->set(1,1,1);
is_deeply( $map->data, [[1,0], [0,1]], 'set' );
is( $map->get(0,0), 1 );
is( $map->get(0,1), 0 );
is( $map->get(1,0), 0 );
is( $map->get(1,1), 1 );
is( $map->get(200,0), 0 );
is( $map->to_string, "\e[48;5;196m \e[0m\e[48;5;16m \e[0m\n\e[48;5;16m \e[0m\e[48;5;196m \e[0m\n" );
is( "$map", $map->to_string );
$map->inc(0,0);
is( $map->get(0,0), 2 );
is_deeply( $map->data, [[1,0], [0,0.5]], 'inc' );
$map->set(0,3,1);
is( $map->get(0,3), 1 );
is( $map->get(1,3), 0 );
is_deeply( $map->data, [[1,0], [0,.5], [0,0], [.5,0]], 'extend y' );
$map->set(3,0,1);
is( $map->get(3,0), 1 );
is( $map->get(3,1), 0 );
is_deeply( $map->data, [[1,0,0,.5], [0,.5,0,0], [0,0,0,0], [.5,0,0,0]], 'extend x' );
( run in 1.062 second using v1.01-cache-2.11-cpan-49f99fa48dc )