# histogram and perl

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on
Hi folks,
I am stuck with a problem. Here it is:
I have got an @array1 and I would like to calculate the frequency of
its element by a range. In few words, build an histogram.
this is my ex code:

#!/usr/bin/perl -w

@value = (48,49,50,46,47,47,35,38,40,42,45,47,48,44,43,46,45,42,43,47);

@sort = sort @value;

\$last=\$sort[\$#sort];

\$range = \$last - \$sort[0];

\$classes=5;

\$interval = \$range / \$classes;

\$count=0;
\$tot=\$sort[0];
while (\$count<\$classes){
#  print "\$tot\n";
\$i=\$tot;
\$tot=\$tot+\$interval;
\$hash=\$tot;
#   print "\$tot\n";
#   print "---\n";
++\$count;
}

\$j=1;
@new=\$sort[0];
foreach \$key (sort<=>\$hash} keys %hash){
print "interval \$j \$key =>> \$hash\n";
push @new,\$hash;
++\$j;
}

# that's wrong..I know :) but it is just to explain what I am trying
to do
#in fact it gives weird results, as 35 > 40...

for (\$im=0;\$im<\$#sort;++\$im){
foreach \$key (sort<=>\$hash} keys %hash){
if ((\$sort[\$im]>\$key) && (\$sort[\$im]<\$hash)){
print "\$sort[\$im]>\$key && \$sort[\$im]<\$hash\n";
}
}
}

../hystogram.pl

interval 1 35 =>> 38
interval 2 38 =>> 41
interval 3 41 =>> 44
interval 4 44 =>> 47
interval 5 47 =>> 50

what I don't know how to do it is to calculate the frequency of my
@value element respect to the five intervals. I should get an output
like that, with an extra column, which represents the frequency:

interval 1 35 =>> 38 1
interval 2 38 =>> 41 2
interval 3 41 =>> 44 4
interval 4 44 =>> 47 5
interval 5 47 =>> 50 8

thanks for any help

regards

andrea

ps. BTW, I need to feed then gnuplot for making the graph.

## Re: histogram and perl

> Hi folks,
> I am stuck with a problem. Here it is:
> I have got an @array1 and I would like to calculate the frequency of
> its element by a range. In few words, build an histogram.
> this is my ex code:
>
> #!/usr/bin/perl -w

No strict, no warnings.

> @value = (48,49,50,46,47,47,35,38,40,42,45,47,48,44,43,46,45,42,43,47);
>
> @sort = sort @value;
>
> \$last=\$sort[\$#sort];
>
> \$range = \$last - \$sort[0];

There is no need to sort the array.  All you need is the maximum and
the minimum.  List::Util can give you those.

> \$classes=5;
>
> \$interval = \$range / \$classes;
>
> \$count=0;
> \$tot=\$sort[0];
> while (\$count<\$classes){
>     #  print "\$tot\n";
>     \$i=\$tot;
>     \$tot=\$tot+\$interval;
>     \$hash=\$tot;
>     #   print "\$tot\n";
>     #   print "---\n";
>     ++\$count;
> }

> \$j=1;
> @new=\$sort[0];
> foreach \$key (sort<=>\$hash} keys %hash){
>     print "interval \$j \$key =>> \$hash\n";
>     push @new,\$hash;
>     ++\$j;
> }
>
> # that's wrong..I know :) but it is just to explain what I am trying
> to do

Frankly, I'm not sure what you're up to with that code.  The verbal
description was clearer :)

In any case, a hash is probably not the structure you want to use
for this problem.

[snip]

There must be lots of ways to do this.  I'd define a function that
maps a value onto its class number, given the value, the range and
the number of classes.

sub range_number {
my ( \$x, \$a, \$b, \$n) = @_;
int (\$x - \$a)*\$n/( \$b - \$a);
}

We'll also want a (kind of) inverse of that function:  Given a class
number, return the range:

sub range {
my ( \$i, \$a, \$b, \$n) = @_;
my \$from = \$a + \$i*(\$b - \$a)/\$n;
my \$to = \$from + (\$b - \$a)/\$n;
( \$from, \$to);
}

Now build the histogram in an array:
use List::Utils qw( min max);

my @value = (48,49,50,46,47,47,35,38,40,42,45,47,48,44,43,46,45,42,43,47);
my \$a = min( @value);
my \$b = max( @value);
my \$n = 5;

my @histo = ( 0) x \$n;
\$histo[ range_number( \$_, \$a, \$b, \$n)] ++ for @value;

....and show it:

for ( 0 .. \$#histo ) {
my ( \$from, \$to) = range( \$_, \$a, \$b, \$n);
print "\$_: [\$from, \$to] -> \$histo[ \$_]\n";
}

Anno

## Re: histogram and perl

> Now build the histogram in an array:
>     use List::Utils qw( min max);

it works with List::Util (as you said earlier) :)
except that, it works perfectly.
thanks
andrea

## Re: histogram and perl

spiritelllo@interfree.it (Andrea Spitaleri) wrote in

> Hi folks,
> I am stuck with a problem. Here it is:

....

> ps. BTW, I need to feed then gnuplot for making the graph.

I am assuming this not a learning exercise: