Cookie Notice

As far as I know, and as far as I remember, nothing in this page does anything with Cookies.

2010/01/14

Making Pretty Pictures

GD::Graph


R


Chart::Clicker
This should have times across the bottom. It doesn't. I don't know why.

These three images are of the same thing, graphed with different tools. I start by getting the data for these arrays out of the database:






















@number #temp_f @date
1 33 14:20
2 35 15:00
3 36 16:00
4 37 17:00
5 37 18:00
6 35 19:00
7 33 20:00
8 32 21:00
9 33 22:00
10 32 23:00
11 32 00:00
12 32 01:00
13 32 02:00
14 32 03:00
15 30 04:00
16 30 05:00
17 30 06:00
18 29 07:00
19 30 08:00
20 32 09:00


These three examples use the same basic information to draw the graph.

The database code


  1. #!/usr/bin/perl  
  2.   
  3. ####################################  
  4. ######   Draw Weather Graph   ######  
  5. ####################################  
  6.   
  7. use 5.010 ;  
  8. use strict ;  
  9. use warnings ;  
  10.   
  11. use Chart::Clicker;  
  12. use Chart::Clicker::Context;  
  13. use Chart::Clicker::Data::DataSet;  
  14. use Chart::Clicker::Data::Marker;  
  15. use Chart::Clicker::Data::Series;  
  16. use Chart::Clicker::Renderer::Area;  
  17. use Chart::Clicker::Renderer::Point;  
  18. use Chart::Clicker::Renderer::StackedArea;  
  19. use Geometry::Primitive::Rectangle;  
  20. use Geometry::Primitive::Circle;  
  21. use Graphics::Color::RGB;  
  22. use Graphics::Primitive::Font;  
  23. use Graphics::Primitive::Brush;  
  24.   
  25. use Data::Dumper ;  
  26. use DBI ;  
  27. use Getopt::Long ;  
  28. use IO::Interactive qw{ interactive } ;  
  29.   
  30. use lib '/home/jacoby/lib' ;  
  31. use MyDB 'db_connect' ;  
  32. use subs qw{  
  33.     high low mean median mode range  
  34.     } ;  
  35.   
  36. my $dbh = db_connect() ;  
  37. my $sql ;  
  38.   
  39. $sql .= 'SELECT  ' ;  
  40. $sql .= 'time , ' ;  
  41. $sql .= 'temp_f   ' ;  
  42. $sql .= 'FROM weather WHERE zip = "47909"  ' ;  
  43. $sql .= 'AND HOUR( TIMEDIFF( SYSDATE() , time ) ) < 25 ' ;  
  44. $sql .= 'GROUP BY HOUR(time)' ;  
  45. $sql .= 'ORDER BY time' ;  
  46.   
  47. my $hr = $dbh->selectall_arrayref( $sql ) or croak $dbh->errstr ;  
  48. my %tg ;  
  49.   
  50. my @temp_f ;  
  51. my @date ;  
  52. my @number ;  
  53. my $count = 1 ;  
  54.   
  55. for my $a ( @$hr ) {  
  56.     $$a[0] = join ':' , ( split m{:} , ( split m{\s}mx , $$a[0] )[1] )[0..1];  
  57.     push @date   , $$a[0] ;  
  58.     push @temp_f , $$a[1] ;  
  59.     push @number , $count++ ;  
  60.     }  


Making the GD PNG


  1. my @data = (  
  2.     [@date] ,  
  3.     [@temp_f]  
  4.     ) ;  
  5.   
  6. my $graph = new GD::Graph::lines( 500,200 )  or die;  
  7. $graph->set(  
  8.       x_label           => 'Temperature',  
  9.       y_label           => 'Time',  
  10.       bgclr             => 'white' ,  
  11.       transparent       => 0 ,  
  12.       title             => 'Lafayette,IN Temperatures in F for the last 24 Hours',  
  13.   ) or die $graph->error;  
  14. $graph->set_title_font( '/home/jacoby/.fonts/trebuc.ttf' , 12 )  or die $graph->error;  
  15. $graph->set_legend_font( '/home/jacoby/.fonts/trebuc.ttf' , 8 )  or die $graph->error;  
  16. $graph->set_x_label_font( '/home/jacoby/.fonts/trebuc.ttf' , 10 )  or die $graph->error;  
  17. $graph->set_y_label_font( '/home/jacoby/.fonts/trebuc.ttf' , 10 )  or die $graph->error;  
  18. my $gd = $graph->plot(\@data) or die $graph->error;  
  19.   
  20. open(IMG, '>' , '/home/jacoby/Desktop/24gd.png') or die $!;  
  21. binmode IMG;  
  22. print IMG $gd->png;  



Making the R output


  1. my $number =  join ',' , @number;  
  2. my $temp_f =  join ',' , @temp_f ;  
  3. my $date =  join ' , ' , ( map { qq("$_") }  @date );  
  4.   
  5. my $r = <<"R" ;  
  6. #x <- (1:24)  
  7. x <- c( $number )  
  8. #x <- c( $date )  
  9. data <- c( $temp_f )  
  10. png(filename='/home/jacoby/Desktop/24r.png', width=500 ,height=200 )  
  11. plot(  
  12.     x ,  
  13.     data ,  
  14.     type='l',  
  15.     main='Lafayette,IN Temperatures in F for the last 24 Hours',  
  16.     xlab='Time' ,  
  17.     ylab='Temperature (f)'  
  18.     )  
  19. #axis( 1 , at=1:48 )  
  20. dev.off()  
  21. R  
  22.   
  23. open my $rh , '>' , '/home/jacoby/Desktop/24r.R' ;  
  24. say $rh $r ;  

Which then has R CMD BATCH filename.R run on it to plot the graph. I could put that in as a qx{} bit, but I didn't here. Normally, yes, I would and in fact we have several that do.


Making the Chart::Clicker PNG


  1. my $cc = Chart::Clicker->new(width => 500, height => 200, format => 'png');  
  2. my $series1 = Chart::Clicker::Data::Series->new(  
  3.     keys    => \@number ,  
  4.     values  => \@temp_f ,  
  5.     );  
  6. my $dataset = Chart::Clicker::Data::DataSet->new(  
  7.     series  => [ $series1 ] ,  
  8.     );  
  9.   
  10. $cc->title->text('Lafayette,IN Temperatures in F for the last 24 Hours');  
  11. $cc->add_to_datasets($dataset);  
  12.   
  13. $cc->get_context('default')->domain_axis->tick_values($series1->keys);  
  14. $cc->get_context('default')->domain_axis->tick_labels(\@date);  
  15. $cc->get_context('default')->domain_axis->tick_label_angle(1);  
  16.   
  17. $cc->get_context('default')->domain_axis->fudge_amount( 0.05 );  
  18. $cc->get_context('default')->range_axis->fudge_amount( 0.1 );  
  19.   
  20. my $defctx = $cc->get_context('default');  
  21. $defctx->range_axis->label( ' Temperature ' );  
  22. $defctx->domain_axis->label('Time');  
  23. $defctx->renderer->brush->width(2);  
  24. $cc->write_output('/home/jacoby/Desktop/24cc.png');  

The big win is that it's graphed right. The next win is that it's all Perl, so I don't need to go back and run a plotter on the output. The last win is that it looks good.

BTW, I find it interesting that, at least on Jan 14 2010, when I do an image search on Chart::Clicker, this blog gets the top spot.

No comments:

Post a Comment