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

Hi, I am having a few problems with the following code. I want to plot a basic line graph using data from a txt file.
X Y 1 10 2 20 3 30 ETC
open (FH, "<data.txt"); while (<FH>) { chomp ($_); ($x, $y) = split (/\s+/, $_) unless /RT/; push @array, ($x, $y); } my $mygraph = GD::Graph::lines->new(600, 300); $mygraph->set( x_label => 'RT', y_label => 'HEIGHT', title => 'xxx' ); $image = $mygraph->plot(\@array) or die $mygraph->error; open(IMG, '>file2.png') or die $!; binmode IMG; print IMG $image->png; close IMG;
i dont think i am using the array correctly though? Any suggestions would be great

Replies are listed 'Best First'.
Re: line graph GD::GRAPH
by ishnid (Monk) on May 19, 2005 at 16:06 UTC
    The arrayref that needs to be passed to the plot() method is quite complex. It needs a reference to an array of array references (if you can get your head around that!). The first arrayref in @array contains the values for x that you want to plot y-values for. Each additional arrayref contains the y-values for one line. Like this:
    open (FH, "<data.txt"); while (<FH>) { chomp ($_); ($x, $y) = split (/\s+/, $_) unless /RT/; push @xes, $x; push @ys, $y; } my $mygraph = GD::Graph::lines->new(600, 300); $mygraph->set( x_label => 'RT', y_label => 'HEIGHT', title => 'xxx' ); $image = $mygraph->plot( [ \@xes, \@ys ] ) or die $mygraph->error; open(IMG, '>file2.png') or die $!; binmode IMG; print IMG $image->png; close IMG;
Re: line graph GD::GRAPH
by ikegami (Patriarch) on May 19, 2005 at 16:07 UTC

    Update: ishnid's right, the data needs to be grouped by axis, not by point. In his answer, he did miss the bit about your push needing the same unless as your split.

    The data needs to be organized into a 2d array. Try changing
    push @array, ($x, $y);
    to
    push @array, [$x, $y];
    push @{$array[0]}, $x;
    push @{$array[1]}, $y;

    Also, I think the first row of the array need to be labels. I'd try adding
    @array = (['RT', 'HEIGHT']);
    before the while.

    You're unless /RT/ needs to be extended to the push.

    I'm really just guessing from a glance at the docs. I don't have any experince this module.

      You're correct that it needs to be a 2d array, however you don't have the construction of it quite right. The first arrayref in @array will be the x-values (1 and 10 in this case) and each additional array contains the corresponding y-values (2 and 20, and 3 and 30). This will actually draw two lines, with the following points:

      (1,2) (10,20)
      (1,3) (10,30)

        I concur. I've updated my post.