Re: create arrays for GD::Graph::lines



On 22 Nov 2006 at 17:35, Rob Dixon wrote:

Beginner wrote:
On 22 Nov 2006 at 15:14, Beginner wrote:

[snip]

The number of years can vary so you might get data from 2006->1990.

The data looks like it is suited to a hash but GD::lines wants the
data passed to in as arrays references (\@array). That is one array
with all the "ancode_n" and foreach code, an array of all the yearly
values. I have managed to get my data into this type of structure

'ADV ' => [
'117216',
'104776',
]
'BAP ' => [
'0',
'270',
],

But I am stuck trying to get it out into n number of arrays that I
can pass to GD. I don't want to pre-declare n number of arrays as the
number may vary and because I am using strict, I don't know how I can
pass the data out of whatever loop I use to get to the values.
[snip]

OK that should work, you've got your codes into a list of legends now. There's
no need for the reverse if you use unshift instead of push to add the values to
the array. And what are you doing for a list of x-values (the years)?

I understood you to mean that there may be gaps in the data, which is another
reason why I said you needed to store hashes of data relating to the years. It
also looked from your code like the data wasn't very well behaved, as you had
allowed for a given year being repeated in some cases. If it's always complete
and in reverse-year order then things are a lot easier. This program keeps your
original data format and produces the same output as my previous effort.



use strict;
use warnings;

use GD::Graph::lines;
use CGI qw/:standard/;

my $q = new CGI;

my %years;
my %values;

foreach my $par ($q->param) {

my $val = $q->param($par);
$val =~ s/\s+$//;

if ($par =~ /(\w{3})_(\d{4})/ ) {
my ($ancode, $yr) = ($1, $2);
$years{$yr}++;
unshift @{$values{$ancode}}, $val;
}
}

my @ancodes = sort keys %values;
my $gdata = [
[sort keys %years],
@values{@ancodes},
];

my $graph = GD::Graph::lines->new(600, 400);
$graph->set_legend(@ancodes);
my $gd = $graph->plot($gdata);


I have come unstuck. I showed the results to the MD and he said
"perhaps it would look better if all the years were sorted" ,highest
to lowest based on the current year. So i began tinkering with Rob's
last post so I had a hash with the keys as the ancode (ADV) and their
values are a hash of the years and their values. It looks a bit like
this:

$VAR1 = {
'ADV' => {,
'2005' => '104776',
'2004' => '85515',
'2006' => '117619',
'2003' => '117007',
},
'PRO' => {,
'2005' => '49684',
'2004' => '39446',
'2006' => '49876',
'2003' => '45674',
},

which I got with this

use strict;
use warnings;
...snip
my $current_year;
my $year_counter = 0;

foreach my $par ($q->param) {
++$year_counter;
my $val = $q->param($par);
$val =~ s/\s+$//;

if ($par =~ /(\w{3})_(\d{4})/ ) {
my ($ancode, $yr) = ($1, $2);
($current_year) = $yr if ($year_counter == 2 ); # current year is
always 2nd param.
$values{$ancode}{$yr} = $val;
}
}
print STDERR "Current year is $current_year\n";

So I need to sort all the code values based on 2006 and then output
the codes in that order.

This seems to sort all the codes in order based on 2006:

my @ancodes = keys %values;
my @sorted_crnt_year = sort { $values{$a}{$current_year} <=>
$values{$b}{$current_year} } @ancodes;

What I can work out of how to pass the data to GD::Graph::Data. What
I have at the moment gives me all the values for a given code
together, rather than separated by years.

my $gdata = new GD::Graph::Data;

foreach my $code (@sorted_crnt_year) {
foreach my $y (keys %years) {
print STDERR "Code=$code,YR=$y,
Val=",$values{$code}{$y},"\n";
$gdata->add_point($code,$values{$code}{$y});
}
}

Can anyone help me with mapping the add_point so that the data is
segragated into years, but keeping the order of @sorted_crnt_year?

TIA.
Dp.



========= As it stands ===========

use strict;
use warnings;

use GD::Graph::bars;
use GD::Graph::Data;
use CGI qw/:standard/;
use Data::Dumper;

my $q = new CGI;

my %values;
my %years;
my $values;
my @param_names = $q->param;
my $current_year;
my $year_counter = 0;

foreach my $par ($q->param) {
++$year_counter;
my $val = $q->param($par);
$val =~ s/\s+$//;

if ($par =~ /(\w{3})_(\d{4})/ ) {
my ($ancode, $yr) = ($1, $2);
($current_year) = $yr if ($year_counter == 2 );
$years{$yr}++;
$values{$ancode}{$yr} = $val;
}
}
print STDERR "Current year is $current_year\n";
my @ancodes = sort keys %values;

# Sort the values of the current year nad store the code
my @sorted_crnt_year = sort { $values{$b}{$current_year} <=>
$values{$a}{$current_year} } @ancodes;

my $gdata = new GD::Graph::Data;

foreach my $code (@sorted_crnt_year) {
foreach my $y (keys %years) {
print STDERR "Code=$code,YR=$y,
Val=",$values{$code}{$y},"\n";
$gdata->add_point($code,$values{$code}{$y});
}
}
#open my $fh, '> plot.gif' or die $!;
#binmode $fh;
#print $fh $gd->gif;
#close $fh;

my $format = $graph->export_format;
print header("image/$format");
binmode STDOUT;
print $graph->plot($gdata)->$format or die $graph->error;

======================

.



Relevant Pages

  • working with 3-dimensional array
    ... I'm trying to read in two file sets of library records, compare a regex that I find in different lines of each set of records, and then copy one whole line over to the other when a match is found. ... I think that I am reading and pushing the arrays onto the other arrays correctly, but when I'm traversing the arrays to do the conditionals, I am getting uninitialized value warnings, which seems like I'm either not traversing correctly OR I'm not really pushing the data onto the arrays properly. ... sub read_records {# read in whole MARC record and push it to @marc ... the foreach $sl loop ...
    (perl.beginners)
  • RE: hash assign not working
    ... Obviously I need the entire arrays and their associated key/value ... so I tried the foreach in the next line. ... Derek Bellner Smith ...
    (perl.beginners)
  • Re: Iterating a Foreach loop for dummies...
    ... I have rearranged the posting accordingly. ... >> I am running into an issue regarding three Foreach loops- one running ... Then the second of all three arrays are printed. ... "Reply" at the bottom of the article headers. ...
    (comp.lang.perl.misc)
  • Re: list of lists
    ... Subject: list of lists ... foreach my $category (sort keys %categories){ ... push @tmp,$poi_num; ...
    (perl.beginners)
  • Re: using [] inside eval function
    ... I'm using eval and arrays in foreach and have trouble with adding ... // creates arrays with the names of columns in keys array ...
    (comp.lang.php)