** Summary ** [GWM]: Based on [A Little graph Plotter]. ** See Also ** [Fun with Functions]: [Another Graphing Widget]: ** Description ** 2006-05: corrected for missing proc. Modified to draw a set of points or multiple sets of points on a canvas. The proc plot takes a list of data to be plotted and a set of titles (one per graph). The data format is: [[list of xposition [[list of ypositions (1,2 or more)]]]] eg: ====== set res [[0.0 {0.0 1.0} 0.333 {0.327 0.944 } 0.6667 {0.618 0.785}]] ====== will define 3 points at x = 0, .333, .6667 with 2 y coordinates per x position (2 graphs). Better example data at the end of this page. ====== #! /bin/env tclsh package require Tk package require math proc graphscale {v vmin vmax pixels} { return [expr {$pixels*($v-$vmin)/($vmax-$vmin)}] } proc plot {res titles} { # adapted the simple graph plotter, http://wiki.tcl.tk/8552 # -------------------------- # params # -------------------------- # title # canvas width & height array set params { title {Graph} width 400 height 400 colors {ff 00 00} } # canvas if [winfo exists .c] { ;# delete it. Same as clear. destroy .c } canvas .c -width $params(width) -height $params(height) \ -xscrollincrement 1 -bg beige pack .c wm title . $params(title) # get range of x & y set xmin 100000000 set xmax -100000000 set ymin 100000000 set ymax -100000000 set vv0 [lindex $res 1] set nvars [llength $vv0] foreach {r y} $res { set xmin [::math::min $xmin $r] set xmax [::math::max $xmax $r] foreach yv $y { ;# get range of Y coordinate set ymin [::math::min $ymin $yv] set ymax [::math::max $ymax $yv] } } #how often tick marks puts "whoo: $xmin" set tspace [expr ($xmax-$xmin)/8.0] ;# how often to draw grid in X puts "tspace: $tspace" set nexttic [expr int($xmin/$tspace)*$tspace] foreach {r y} $res { ;# draw grid if {$r >= $nexttic} { set xpix [graphscale $nexttic $xmin $xmax $params(width)] set nexttic [expr $nexttic+$tspace] .c create text [expr $xpix-10] 0 -anchor n -text [format %.2f $r] \ -fill gray .c create line $xpix 0 $xpix $params(height) -fill gray } } #how often Ytick marks set tspace [expr ($ymax-$ymin)/8.0] ;# how often to draw grid in X set nexttic [expr int($ymin/$tspace)*$tspace] while {$nexttic < $ymax} { ;# draw grid set ypix [graphscale $nexttic $ymax $ymin $params(height)] set nexttic [expr $nexttic+$tspace] puts "whack: $nexttic" .c create text 20 [expr $ypix-10] -anchor n -text [format %.2f $nexttic] \ -fill gray .c create line 0 $ypix $params(width) $ypix -fill gray } set lastheight $params(height) for {set iy 0} {$iy<$nvars} {incr iy} { lassign $params(colors) red green blue lappend params(colors) $red set params(colors) [lreplace $params(colors) 0 0] #label graph puts "huh: $red$green$blue" set title [lindex $titles $iy] .c create text -1000 0 -anchor n -text $title \ -fill #$red$green$blue -tag $title lassign [.c bbox $title] textx1 texty1 textx2 texty2 set textwidth [expr {abs($textx2-$textx1)}] set textheight [expr {abs($texty2-$texty1)}] .c coords $title [expr {$params(width)-$textwidth}] \ [set lastheight [expr {$lastheight-$textheight}]] set coordlist {} foreach {r y} $res { set xpix [graphscale $r $xmin $xmax $params(width)] set vv [lindex $y $iy] set v [graphscale $vv $ymax $ymin $params(height)] lappend coordlist $xpix $v set rold $xpix set yold $v ;# vector of y values } .c create line $coordlist -fill #$red$green$blue } } #Exercise the graph thus: set plot [list] for {set i 0} {$i<20} {incr i} { set plot [linsert $plot 0 [expr $i/3.0] [expr sin($i/3.0)]] } plot $plot Sine # Or 2 graphs (values of sin(x) and cos(x) are placed in a list of results at x): set plot [list] for {set i 0} {$i<20} {incr i} { lappend plot [expr $i/3.0] [list [expr sin($i/3.0)] \ [expr cos($i/3.0)]] } plot $plot {Sine Cos} ====== ** Misc ** [DPO]: In the plot proc above, there is a call to a "scale" command. This does not match the tk usage which requires a path as the first arg. What "scale" command is this? It fails for me. (I am forced to use tcl 8.0.5 due to API limitations) [GWM]: Sorry, a bit slow to respond here... supplied new function graphscale and renamed old proc scale to graphscale. This works a bit better. <> Plotting