Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Simple Text Histogram

by larryl (Scribe)
on Mar 18, 2001 at 06:28 UTC ( #65228=snippet: print w/replies, xml ) Need Help??
Description:

This is based on a simple text histogram I added to jcwren's statswhore.pl. Works with an array of integers, but could easily be extended for floating point values. You can set the bin size for dividing up your data. Does some simple scaling to keep things within one screen width.

Creates output something like:

-5 .. -1 [ 1] # 0 .. 4 [ 7] ####### 5 .. 9 [ 6] ###### 10 .. 14 [ 7] ####### 15 .. 19 [ 3] ### 20 .. 24 [ 1] #

Update: Changed name of bins hash to %bin_counts and fixed a bug with width scaling, both pointed out by tilly. Thanks for the feedback tilly!

sub show_histogram
{
   # Prints a simple text histogram given a reference
   # to an array of integers.
   # Larry Leszczynski <larryl@furph.com>

   my ($array_ref, $binsize, $width) = @_;
   $binsize ||= 1;
   $width   ||= 50;

   use POSIX qw(ceil floor);

   # Divide input data into bins:
   my %bin_count = ();   # number of items in each bin
   foreach ( @$array_ref ) {
      my $bin = floor(($_+.5)/$binsize);
      $bin_count{$bin}++;
   }

   my $max_items = 0;   # maximum items in a single bin
   foreach ( values %bin_count ) {
      $max_items = $_ if $_ > $max_items;
   }

   # Try to keep histogram on one page width:
   my $scale = 1;
   if ( $max_items > $width ) {
      if ( $max_items <= ($width*5) ) {
         $scale = 5;
      }
      else {
         while ( ($max_items/$scale) > $width ) {
            $scale *= 10;
         }
      }
   }

   my @bins   = sort {$a <=> $b} keys %bin_count;
   my $bin    = $bins[0];    # lowest value bin
   my $maxbin = $bins[-1];   # highest value bin

   my $binfmt_width = ( length $maxbin > length $bin )
                      ? length $maxbin : length $bin;
   my $cntfmt_width = length $max_items;

   my $start = $bin * $binsize;
   my $end   = $start + $binsize - 1;
   do {
      my $count = $bin_count{$bin} || 0;
      my $extra = ( $count % $scale ) ? '.' : '';
      printf "%*d .. %*d  \[%*d\] %s$extra\n",
                    $binfmt_width, $start,
                    $binfmt_width, $end,
                    $cntfmt_width, $count,
                    '#' x ceil($count/$scale);
      $start += $binsize;
      $end   += $binsize;
   } while ( $bin++ < $maxbin );
   print "\n  Scale: #=$scale\n" if $scale > 1;
}
Replies are listed 'Best First'.
Re: Simple Text Histogram
by Anonymous Monk on May 09, 2002 at 18:43 UTC
    Can you tell me how I call this function? (e.g. what is the input to it like)? I tried show_histogram(@foo) where @foo = (1,2,3,4,5,6) and got garbage... thanks!
      It expects an array reference so try show_histogram(\@foo);
        Yup, calling it with ( \@array_name, size_of_bin, width ) works, but the output stuff could do with tons of improvement. Documentation leaves something to be desired. But, it does work:)
Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://65228]
help
Chatterbox?
[marto]: hey virtualsue!
Eily thought about Neko Case first, something might be wrong with my brain's wiring
[virtualsue]: I recommended dbic-migration even though I am having trouble with it this week. It might be my fault.
[ambrus]: wow! I haven't seen you here for a long time, virtualsue
virtualsue waves back
[Eily]: it would have been 2 years in 2 weeks actually. And welcome back virtualsue :)
[Corion]: I think I saw virtualsue more recently in person than online :-D
[virtualsue]: It's true that there was a bigger gap between the 2 yr old post and the one before it
[ambrus]: yes, I probably just didn't see you two years ago, because I'm not in perlmonks much
[virtualsue]: Nor am I :-)

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (12)
As of 2017-09-26 13:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    During the recent solar eclipse, I:









    Results (295 votes). Check out past polls.

    Notices?