Arjen Markus (29 september 2009) on the comp.lang.tcl newsgroup Stuart asked for a script to plot wind roses. As I had some time on my hands, I did a first implementation of such a diagram using Plotchart. The result is below.
AM (22 october 2009) I have added this to Plotchart, along with some new plot methods.
# windrose.tcl -- # Add a wind rose diagram to Plotchart # # package -- # Register the new plot type # package require Plotchart namespace eval ::Plotchart { set methodProc(windrose,plot) DrawWindRoseData set methodProc(windrose,saveplot) SavePlot set methodProc(windrose,title) DrawTitle } # createWindRose -- # Create a new command for plotting a windrose # # Arguments: # w Name of the canvas # radius_data Maximum radius and step # sectors Number of sectors (default: 16) # Result: # Name of a new command # Note: # The entire canvas will be dedicated to the windrose # Possible additional arguments (optional): nautical/mathematical # step in phi # proc ::Plotchart::createWindRose { w radius_data {sectors 16}} { variable data_series foreach s [array names data_series "$w,*"] { unset data_series($s) } set newchart "windrose_$w" interp alias {} $newchart {} ::Plotchart::PlotHandler windrose $w set rad_max [lindex $radius_data 0] set rad_step [lindex $radius_data 1] if { $rad_step <= 0.0 } { return -code error "Step size can not be zero or negative" } if { $rad_max <= 0.0 } { return -code error "Maximum radius can not be zero or negative" } lassign [MarginsCircle $w] pxmin pymin pxmax pymax viewPort $w $pxmin $pymin $pxmax $pymax polarCoordinates $w $rad_max DrawRoseAxes $w $rad_max $rad_step set data_series($w,radius) {} for { set i 0 } { $i < $sectors } { incr i } { lappend data_series($w,cumulative_radius) 0.0 } set data_series($w,start_angle) [expr {90.0 - 360.0/(4.0*$sectors)}] set data_series($w,d_angle) [expr {360.0/(2.0*$sectors)}] set data_series($w,increment_angle) [expr {360.0/$sectors}] set data_series($w,count_data) 0 return $newchart } # DrawRoseAxes -- # Draw the axes to support a wind rose # Arguments: # w Name of the canvas # rad_max Maximum radius # rad_step Step in radius # Result: # None # Side effects: # Axes drawn in canvas # proc ::Plotchart::DrawRoseAxes { w rad_max rad_step } { # # Draw the spikes # set angle 0.0 lassign [polarToPixel $w 0.0 0.0] xcentre ycentre foreach {angle text dir} { 90 North s 180 West e 270 South n 0 East w } { lassign [polarToPixel $w $rad_max $angle] xcrd ycrd lassign [polarToPixel $w [expr {1.05*$rad_max}] $angle] xtxt ytxt $w create line $xcentre $ycentre $xcrd $ycrd $w create text $xtxt $ytxt -text $text -anchor $dir } # # Draw the concentric circles # set rad $rad_step while { $rad < $rad_max+0.5*$rad_step } { lassign [polarToPixel $w $rad 45.0] xtxt ytxt lassign [polarToPixel $w $rad 0.0] xright ycrd lassign [polarToPixel $w $rad 180.0] xleft ycrd lassign [polarToPixel $w $rad 90.0] xcrd ytop lassign [polarToPixel $w $rad 270.0] xcrd ybottom $w create oval $xleft $ytop $xright $ybottom $w create text $xtxt [expr {$ytxt+3}] -text $rad -anchor s set rad [expr {$rad+$rad_step}] } } # DrawWindRoseData -- # Draw the data for each sector # Arguments: # w Name of the canvas # data List of "sectors" data # colour Colour to use # Result: # None # Side effects: # Data added to the wind rose # proc ::Plotchart::DrawWindRoseData { w data colour } { variable data_series set start_angle $data_series($w,start_angle) set increment $data_series($w,increment_angle) set width_sector $data_series($w,d_angle) set new_cumulative {} foreach value $data cumulative_radius $data_series($w,cumulative_radius) { console show ; puts $start_angle set radius [expr {$value + $cumulative_radius}] lassign [polarToPixel $w [expr {$radius*sqrt(2.0)}] 45.0] xright ytop lassign [polarToPixel $w [expr {$radius*sqrt(2.0)}] 225.0] xleft ybottom $w create arc $xleft $ytop $xright $ybottom -style pie -fill $colour \ -tag data_$data_series($w,count_data) -start $start_angle -extent $width_sector lappend new_cumulative $radius set start_angle [expr {$start_angle - $increment}] } $w lower data_$data_series($w,count_data) set data_series($w,cumulative_radius) $new_cumulative incr data_series($w,count_data) } # main -- # Testing the wind rose diagram # pack [canvas .c -bg white] set p [::Plotchart::createWindRose .c {30 6} 4] $p plot { 5 10 0 3} red $p plot {10 10 10 3} blue $p title "Simple wind rose - margins need to be corrected ..."
(06.08.2023) Bug Only works with older Plotchart. :from tklib 0.6, Plotchart2.0.1
arjen - 2023-08-07 06:12:48
Hm, I will have to look into this bug!
(2023-08-08 07:28)
for Plotchart2.0.1 in ::Plotchart::createWindRose missing :
variable scaling set scaling($w,coordSystem) 0 CopyConfig windrose $w
and and ticket for newer Ticket
arjen - 2023-08-13 11:40:54
Thanks - I repaired this in version 2.6.1. See the ticket for more information.