@@ -21,6 +21,8 @@ =head1 DESCRIPTION
2121
2222=item Scatter Plots
2323
24+ =item Pie Charts
25+
2426=back
2527
2628=head2 USAGE
@@ -69,7 +71,7 @@ =head2 BAR PLOTS
6971
7072 $stat_plot->add_barplot($xdata, $ydata, %opts);
7173
72- where C<$xdata > is an ARRAYREF of x-values where the bars will be centered and C<$ydata > is an
74+ where C<$xdata > is an array reference of x-values where the bars will be centered and C<$ydata > is an
7375ARRAY of heights of the bars. Note: if the option C<< orientation => 'horizontal' >> is included
7476then the bar lengths are the values in C<$xdata > and locations in C<$ydata > .
7577
@@ -169,9 +171,19 @@ =head3 Options
169171of points. If the value is 1, then the heights are scaled so the total height of the
170172bars is 1.
171173
174+ =item stroke_color
175+
176+ This sets the color of the boundary of the rectangle and the whiskers. It is an alias for
177+ the C<color > option of L<add_dataset|plots.pl/DATASET OPTIONS> . See L<COLORS|plots.pl> for options to change the color.
178+
179+ =item stroke_width
180+
181+ This sets the width of the boundary of the rectangle and the whiskers. This is an alias for
182+ the C<width > option of L<add_dataset|plots.pl> .
183+
172184=back
173185
174- The rest of the options are passed through to the C <add_barplot > method in which the
186+ The rest of the options are passed through to the L <add_barplot|BAR PLOTS > method in which the
175187fill color and opacity as well as the stroke color and width. See both L<add_barplot>
176188and L<add_dataset options|plots.pl/DATASET OPTIONS> for more details.
177189
@@ -189,8 +201,8 @@ =head2 BOX PLOTS
189201where C<$data > is an array ref of univariate data or a hash ref of the boxplot characteristics,
190202then a box plot is created using the five number summary (minimum, first quartile, median,
191203third quartile, maximum) of the data. These values are calculated using the C<five_point_summary >
192- function from C<PGstatisticsmacros.pl > . An example of creating a boxplot with an arrayref of
193- univariate data is
204+ function from C<PGstatisticsmacros.pl > . An example of creating a boxplot with an array reference
205+ of univariate data is
194206
195207 @data = urand(100,25,75,6);
196208
@@ -211,7 +223,7 @@ =head2 BOX PLOTS
211223and as with other methods in this macro, one can pass options to the characteristic of the
212224box plot (like fill color or stroke color and width) within the C<add_boxplot > method.
213225
214- If C<$data > is a hashref , it must contains the fields C<min, q1, median, q3, max > that are used to
226+ If C<$data > is a hash reference , it must contains the fields C<min, q1, median, q3, max > that are used to
215227define the boxplot. Optionally, one may also include the field C<outliers > which is an array
216228ref of values which will be plotted beyond the whiskers.
217229
@@ -257,7 +269,7 @@ =head3 Options
257269
258270If multiple box plots are included, this option will be created to equally space the
259271box plots between the axis and the edge of the plot. If included, this option must be an
260- arrayref of values (in the x-direction for vertical plots and y-direction for horizontal).
272+ array reference of values (in the x-direction for vertical plots and y-direction for horizontal).
261273
262274 box_center => [3,6,9]
263275
@@ -285,9 +297,19 @@ =head3 Options
285297The shape of the mark to use for outliers. Default is 'plus'. See L<Options for add_dataset|plots.pl/DATASET OPTIONS>
286298for other mark options.
287299
300+ =item stroke_color
301+
302+ This sets the color of the boundary of the rectangle and the whiskers. It is an alias for
303+ the C<color > option of L<add_dataset|plots.pl/DATASET OPTIONS> . See L<COLORS|plots.pl> for options to change the color.
304+
305+ =item stroke_width
306+
307+ This sets the width of the boundary of the rectangle and the whiskers. This is an alias for
308+ the C<width > option of L<add_dataset|plots.pl> .
309+
288310=back
289311
290- As with other methods in the macro, other options can be passed along to C <add_rectangle >
312+ As with other methods in the macro, other options can be passed along to L <add_rectangle|plots.pl/PLOT RECTANGLES >
291313and C<add_dataset > which are used in the macro.
292314
293315Also, if C<fill_color > is included, then C<< fill => 'self' >> is automatically added on the
@@ -332,12 +354,108 @@ =head2 SCATTER PLOTS
332354
333355The C<mark_size > is default to 3.
334356
357+ =item mark_color
358+
359+ This changes the mark color and is an alias for the C<color > option. See L<COLORS/plots.pl>
360+ for options to change the color.
361+
335362=back
336363
337364If more that one dataset is to be plotted, simply call the C<add_scatterplot > method multiple
338365times. This can be done with a single C<add_dataset > method call, but this wrapper makes it
339366easier to set different options
340367
368+ =head2 PIE CHARTS
369+
370+ A pie chart is a circle that divided in to sectors whose size is proportional to an input array.
371+ The sectors are generally given each a color and a label. This method will also produce
372+ donut charts (or ring charts), which is a pie chart with a hole.
373+
374+ The general form is
375+
376+ $stat_plot->add_piechart($data, %options);
377+
378+ where $data is an array reference of values.
379+
380+ The following are the options:
381+
382+ =over
383+
384+ =item center
385+
386+ The center of the circle as an array reference. The default value is C<[0,0] > .
387+
388+ =item radius
389+
390+ The radius of the circle. The default value of C<4 > is chosen to fit nicely with the
391+ default values of the bounding box of the C<StatPlot > which ranges from -5 to 5
392+ in both the x- and y-directions.
393+
394+ =item inner_radius
395+
396+ If you desire a donut chart or ring chart, set this to a value less than the radius.
397+ The default value is 0.
398+
399+ =item angle_offset
400+
401+ The first sector by default starts at angle 0 (from the positive horizontal axis) in degrees. Use
402+ this to change this.
403+
404+ =item color_palette
405+
406+ This is either the name of a color palette or an array reference of colors for each of the
407+ sectors in the pie chart. If the length of this array reference is smaller than
408+ the C<$data > array reference, then the colors will be cycled. The default is to
409+ use the 'default' color palette. See L<COLOR PALETTES> for more information.
410+
411+ =item color_sectors
412+
413+ If this is 1 (default), then colors are used for the pie chart. If 0, then the
414+ sectors are not filled. See C<color_palette > for selecting colors.
415+
416+ =item sector_labels
417+
418+ The labels for the sector as a array reference of strings or values. The default is for
419+ no labels. If this is used, the length of this must be the same as the C<$data > array
420+ reference.
421+
422+ =back
423+
424+ =head2 COLOR PALETTES
425+
426+ The color palettes for the bar plots and pie charts can be select from the C<color_palette >
427+ function. This allows a number of built-in/generated color palettes. To get an
428+ array reference of either named or generated colors:
429+
430+ color_palette($name, num_colors => $n);
431+
432+ For example,
433+
434+ color_palette('rainbow');
435+
436+ returns the 6 colors of the rainbow. Some of the palettes have fixed numbers of colors,
437+ whereas others have variable numbers. If C<num_colors > is not defined, then some palettes
438+ return a fixed number (like 'rainbow') and if the C<num_colors > is needed, then the
439+ default of 10 is assumed.
440+
441+ =head3 PALETTE NAMES
442+
443+ =over
444+
445+ =item rainbow
446+
447+ The colors of the rainbow from violet to red. The C<num_colors > options is ignored.
448+
449+ =item random
450+
451+ This will return C<num_colors > random colors from the defined SVG colors.
452+
453+ =back
454+
455+ =head2 LEGENDS
456+
457+ A legend is helpful for some plots.
458+
341459=cut
342460
343461BEGIN { strict-> import ; }
@@ -399,10 +517,10 @@ sub add_barplot {
399517 my %options = (
400518 bar_width => 1,
401519 orientation => ' vertical' ,
402- %opts
520+ plot_option_aliases( %opts )
403521 );
404522
405- Value::Error(' The lengths of the data in the first two arguments must be arrayrefs of the same length' )
523+ Value::Error(' The lengths of the data in the first two arguments must be array references of the same length' )
406524 unless ref $xdata eq ' ARRAY' && ref $xdata eq ' ARRAY' && scalar (@$xdata ) == scalar (@$ydata );
407525
408526 # assume that the $xdata is equally spaced. TODO: should we handle arbitrary spaced bars?
@@ -430,7 +548,7 @@ sub add_boxplot {
430548 whisker_cap => 0,
431549 cap_width => 0.2,
432550 outlier_mark => ' plus' ,
433- %opts
551+ plot_option_aliases( %opts )
434552 );
435553
436554 # Placeholder for boxplot implementation.
@@ -546,11 +664,110 @@ sub add_scatterplot {
546664 linestyle => ' none' ,
547665 marks => ' circle' ,
548666 mark_size => 3,
549- %opts
667+ plot_option_aliases( %opts )
550668 );
551669
552670 $self -> add_dataset(@$data , %options );
553671
554672}
555673
674+ sub add_piechart {
675+ my ($self , $data , %opts ) = @_ ;
676+
677+ my %options = (
678+ center => [ 0, 0 ],
679+ radius => 4,
680+ angle_offset => 0,
681+ inner_radius => 0,
682+ plot_option_aliases(%opts )
683+ );
684+
685+ Value::Error(' The number of labels must equal the number of sectors in the pie chart' )
686+ unless defined ($options {labels }) && scalar (@$data ) == scalar (@{ $options {labels } });
687+
688+ my $fill_colors =
689+ (!defined $options {fill_colors } || ref $options {fill_colors } ne ' ARRAY' )
690+ ? color_palette($options {fill_colors })
691+ : $options {fill_colors };
692+
693+ my $pi = 4 * atan2 (1, 1);
694+ my $total = 0;
695+ $total += $_ for (@$data );
696+
697+ my $theta = $options {angle_offset } * $pi / 180; # first angle of the sector
698+ for (0 .. $# $data ) {
699+ my $delta_theta = 2 * $pi * $data -> [$_ ] / $total ;
700+ $self -> add_multipath(
701+ [
702+ [
703+ " $options {center}->[0] + $options {radius} * cos(t)" ,
704+ " $options {center}->[1] + $options {radius} * sin(t)" ,
705+ $theta ,
706+ $theta + $delta_theta
707+ ],
708+ [
709+ " $options {center}->[0] + $options {inner_radius} * cos(t)" ,
710+ " $options {center}->[1] + $options {inner_radius} * sin(t)" ,
711+ $theta + $delta_theta ,
712+ $theta
713+ ],
714+ ],
715+ ' t' ,
716+ cycle => 1,
717+ fill => ' self' ,
718+ fill_color => $fill_colors -> [ $_ % scalar (@$fill_colors ) ],
719+ %options
720+ );
721+ # add the labels if defined
722+ if ($options {labels }) {
723+ my $alpha = $theta + 0.5 * $delta_theta ;
724+ # take $alpha mod 2pi
725+ $alpha = $alpha - (2 * $pi * int ($alpha / (2 * $pi )));
726+
727+ $self -> add_label(
728+ 1.1 * $options {radius } * cos ($alpha ),
729+ 1.1 * $options {radius } * sin ($alpha ),
730+ $options {labels }-> [$_ ],
731+ (0 <= $alpha && $alpha < $pi / 4)
732+ || (7 * $pi / 4 < $alpha && $alpha < 2 * $pi ) ? (h_align => ' left' )
733+ : $pi / 4 <= $alpha < 3 * $pi / 4 ? (v_align => ' bottom' )
734+ : 3 * $pi / 4 <= $alpha < 5 * $pi / 4 ? (h_align => ' right' )
735+ : (v_align => ' top' )
736+ );
737+ }
738+ $theta += $delta_theta ;
739+ }
740+
741+ }
742+
743+ # This provides some alias for options.
744+ # For additional aliases, add to the %aliases hash below.
745+
746+ sub plot_option_aliases {
747+ my (%options ) = @_ ;
748+
749+ my %aliases = (
750+ width => ' stroke_width' ,
751+ color => ' stroke_color' ,
752+ color => ' mark_color'
753+ );
754+
755+ for (keys %aliases ) {
756+ $options {$_ } = $options { $aliases {$_ } } if $options { $aliases {$_ } };
757+ delete $options { $aliases {$_ } };
758+ }
759+ return %options ;
760+ }
761+
762+ sub color_palette {
763+ my ($palette_name , $num_colors ) = @_ ;
764+
765+ $palette_name = ' rainbow' unless defined ($palette_name );
766+
767+ if ($palette_name eq ' rainbow' ) {
768+ return [ ' violet' , ' blue' , ' green' , ' yellow' , ' orange' , ' red' ];
769+ }
770+
771+ }
772+
5567731;
0 commit comments