andy_7t has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm trying to create a dynamic set of arrays to pipe into GD::Graph.

This works fine:

@data=([@array1],[@array2],[@array3]); my $gd = $graph->plot(\@data) or die $graph->error;
My question: How do i make @data have X set of arrays.

e.g.

for ($x=1; $x<10; $x++) { @anotherarray=(1,2,3,4,5); push @data, [ @anotherarray ]; } my $gd = $graph->plot(\@data) or die $graph->error;
which should give 9 lines?

I just get no points defined, or more specifically: No data sets or points :-(

UPDATE:
I'll give full details of what i'm trying to do. It's basically a traffic graph from multiple flat text files representing data streams.
They are in the format
TIME(HH:MM:SS):KBITS I open each file:

foreach $file (@files) { undef @timestamp; undef @kbits; open FILE, "$file"; @points=<FILE>; foreach $point (@points) { @split=split /:/, $point; push @timestamp, $split[0]; push @kbits, $split[1]; #### NOW IDEALLY, I WANT TO ADD @kbits TO THE DATA SET ### something like this: push (@data, [ @kbits ] ); #forget the timestamp for now- that just c +omplicates matters! } ## BUT I CAN'T, SO I JUST CURRENTLY TAKE THE LAST SET OF DATA # this gives no error @data=([@timestamp],[@kbits]); I'm using fatalstobrowser so the exact error is: No data sets or points at /home/web/http/volgraph.pl line 250. }

Replies are listed 'Best First'.
Re: GD @data array question
by mr_mischief (Monsignor) on Jan 29, 2009 at 21:58 UTC
    This code gives me a result:

    use strict; use warnings; use GD::Graph::bars; my @data; my $graph = GD::Graph::bars->new( 400, 300 ); for ( my $x=1; $x<10; $x++) { my @anotherarray=(1,2,3,4,5); push @data, [ @anotherarray ]; } my $gd = $graph->plot(\@data) or die $graph->error; open ( my $img, '>file.png') or die $!; binmode $img; print $img $gd->png; close $img;

    The result is five groupings of 8 (not 9, check your loop counter) lines each in a vertical bar chart in a PNG file.

    I'm not sure which portions are different from your entire program, because you provided only a particular portion. That portion may not be the one at fault after all. Be sure to post small yet functional code snippets for the best results. Also, I made what changes were necessary to use the strict and warnings pragmas. That's always a good idea.

    Now that you've seen a working example using your own data structure, you should be able to start comparing things to figure out what else could be wrong.

      OK, i found it. Your going to laugh :-)
      The array I was looping through also put in a MySQL connection - and the data returned was also called @data! Was overwriting my array!
        I didn't laugh, no. At least not at first, I didn't. It was more a cringe. You're not the first person to assume their problem was with something new or complex and overlooked something simple. I think most programmers can identify with that or will eventually. Always remember it's not always where you expect an error to be that you find it.

        In the network administration field, there's an old saying that goes, "physical layer first". You might very well have a corruption in a network stack on some server somewhere, but you'll feel awfully silly if you debug that and find out you just had a bad Ethernet cable. People tend to look for the obvious source of the problem. Sometimes it pays better to look where it's simple to spot a problem even if that's not where you expect to find it.

        Update: Another lesson that "physical layer first" saying tries to teach is that debugging by starting at the lowest level of dependencies and going up the stack from there is quicker than going from the top of the pyramid down. That's not as helpful with software as it might seem, but it is still helpful. Keep in mind, though, that the OS, the OS libraries, and perl have had much more debugging than your code that depends on them. If though, for example, you have your own module and then code on top of it that doesn't behave as you expect, don't be afraid to test and debug your module. Assuming the module works and focusing on the code that uses it can cause one heck of a headache.

        This is one of the main reasons why I find ruby impractical. In perl, I can declare lexical variables, they can shadow each other, perl warns if I use a variable name for two things in the same scope (which I often do accidentally as I use lots of one or two letter long names), dies if I don't declare a variable or if I make a typo in a variable name.

      Thanks,
      Your example works for me too. I'll see where i'm going wrong.
        Note in the docs that GD::Graph's plot() method expects to have the same number of points in every set. The docs suggest providing an explicit undef value for points that are missing from your data (not to be confused with uses of the undef function call). Are your files perhaps not always providing the same number of points?