http://www.perlmonks.org?node_id=990347

cmr72 has asked for the wisdom of the Perl Monks concerning the following question:

Hello All, I am a newbie. I've been a round PERL for a while but never had to really get down to the nitty gritty of it. I am not a programmer and usually troll around looking for answers. Today I created a random number generator in hopes to pipe the output into a histogram set for plotting in GNUPLOT. While I understand how to generate a hash to tally the points, I am totally lost on creating bins, whether automatically spaced or with an argument from the user. Here is the code that I have so far:

Random number generator:

#!/usr/bin/perl -w use strict ; my $samplesize = $ARGV[0] ; my $max = $ARGV[1] ; chomp(my $prog = `basename $0`) ; if ($#ARGV < 1) { print "\nUsage: ./randomnumber.pl <samplesize> <max num>\n" ; exit ; } for (my $i = 0; $i<$samplesize; $i++) { my $range = $max ; my $random_number = int(rand($range)) - $max/2; print "$random_number \n"; }
Histogram creator:
#!/usr/bin/perl -w use strict ; my %bin ; my %size; my %value ; my $max = 0 ; my $min = 0 ; my $count ; while ( <STDIN> ) { my @line= split ; my $element = $line[0] ; $value{$element}++ ; } foreach my $i (sort {$a<=>$b} keys %value) { if ($i > $max) { $max = $i ; } if ($i < $min) { $min = $i ; } }
So if there are values -1, -1.5, -2, 2, 1, 0, 1, I would hope to see the following (if the bin range was between -2:2)

(-2) 3

(0) 1

(2) 3

Or something like that... Thanks in advance.

Replies are listed 'Best First'.
Re: Help with Histograms
by toolic (Bishop) on Aug 29, 2012 at 00:37 UTC
Re: Help with Histograms
by philiprbrenan (Monk) on Aug 29, 2012 at 00:59 UTC

    Given that the input is a sequence of random numbers, you could synthesize your desired arrangement of bins directly with no loss of information:

    use feature ":5.14"; use warnings FATAL => qw(all); use strict; use Data::Dump qw(dump pp); sub bins($$$$)# Fill some bins {my ($start, $count, $width, $samples) = @_; # Start bin, number of b +ins, bin width, number of samples my $bins; $bins->{$start+$width * int(rand $count)}++ for 1..$samples; $bins } pp(bins(-2, 3, 2, 8));

    Produces:

    { "-2" => 4, "0" => 1, "2" => 3 }
    
Re: Help with Histograms
by pvaldes (Chaplain) on Aug 29, 2012 at 15:43 UTC
    #--------------------------- ## hi, I am a gnuplot script and you are probably trying to do in perl + my own job set terminal png large size 1920,1200 set output 'output.png' set style histogram set title "my title" set xlabel "my x varname" set ylabel "my y varname" set yrange [0:10] set style fill solid border -1 binwidth=5 set boxwidth binwidth bin(x,width)=width*floor(x/width) + binwidth/2.0 plot 'mydata.dat' using (bin($1,binwidth)):(1.0) smooth freq with boxe +s #---------------------------
Re: Help with Histograms
by cmr72 (Initiate) on Aug 29, 2012 at 20:00 UTC
    Hey all, thanks for your help. I managed to do the following:
    #!/usr/bin/perl -w use strict ; use POSIX ; my %bin ; my %size; my %value ; my $binwidth = $ARGV[0] ; chomp(my $prog = `basename $0`) ; if ($#ARGV < 0) { print "\nUsage: ./histo.pl.pl <bin width>\n" ; exit ; } while ( <STDIN> ) { my @line= split ; my $element = $line[0] ; $value{ceil(($element+1)/$binwidth)-1}++ } foreach my $i (sort {$a<=>$b} keys %value) { my $bin = $i*$binwidth ; print "$bin $value{$i}\n" ; }