global ready
set ready 0
proc histogram {slist wid ht} { ;# render a histogram
global ready
array set scores $slist
set nms [lsort -integer [array names scores]]
catch {destroy .h} {}
catch {destroy .b} {}
canvas .h -width $wid -height $ht -bg beige
pack .h
set nbars [array size scores] ;#how many histogram bars
set nax [expr $nbars/10] ;# axis spacing
set hwid [expr $wid/ $nbars]
set i 0
set hmax -9999999 ;# largest y value
set hmin 9999999 ;# smallest y value
while {$i<$nbars} {
set f $scores([lindex $nms $i])
set hmax [ expr {$f>$hmax} ? $f : $hmax]
set hmin [ expr {$f<$hmin} ? $f : $hmin]
incr i
}
if {$hmax>$hmin} {
set i 0
set nay 100
while {$nay<$hmax} {
set yp [expr $ht-0.75*$nay-20]
.h create line 0 $yp $wid $yp -fill red
incr nay 100
}
set nax 10
while {$i<$nbars} {
set x [expr $hwid*$i]
set rhs [expr $x+$hwid/2]
set f [expr $ht-20-.75*$ht*$scores([lindex $nms $i])/$hmax]
.h create rectangle $x [expr $ht-20] $rhs $f -fill gray
if {[expr $i>=$nax]} {
.h create line $x [expr $ht-20] $x 0 -fill red
incr nax 10
}
incr i
incr x $hwid
}
update
# button .b -text "Next" -command "incr ready" ;# when ready is changed, proceeds with commands
# pack .b
}
}Call using
histogram {1 2 2 3 3 5 4 7 5 6} 500 400The list is actually an array :: category 1 occurred twice; category 2 three times, category 3 5 times, category 4 7 times & 5 occurred 6 times. The category names must be integers. For a way of looking at the rand function: for {set i 0} {$i<50} {incr i} {lappend scores $i [expr rand()]}
histogram $scores 500 200will show a histogram of the value returned by rand for 50 trials (nb not the frequency).For rand frequency of the first digit returned by rand() use: for {set i 0} {$i<10} {incr i} {set rnd($i) 0}
for {set i 0} {$i<50} {incr i} { incr rnd([expr int(9.9999*rand())])}
histogram [array get rnd] 300 200Repeatedly paste this code into wish console to see the variation in frequency of each integer value.Other graphics routinesSee also
