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

I am having problems getting GD::Graph to function. It seems to have issues constructing graphs when all of the datapoints are the same. This example code works:
#!/usr/local/perl-5.8.3/bin/perl use warnings; use strict; use GD::Graph::lines; my @data = ( [ qw/ 1 2 3 / ], [ qw/ -70 -70 -71 / ], ); my $graph = GD::Graph::lines -> new ( 200, 200 ); $graph -> set( x_label => 'x', y_label => 'y', title => 'title', ); $graph -> plot ( \@data );
while the following code does not:
#!/usr/local/perl-5.8.3/bin/perl use warnings; use strict; use GD::Graph::lines; my @data = ( [ qw/ 1 2 3 / ], [ qw/ -70 -70 -70 / ], ); my $graph = GD::Graph::lines -> new ( 200, 200 ); $graph -> set( x_label => 'x', y_label => 'y', title => 'title', ); $graph -> plot ( \@data );
The second code will run forever (over 5 minutes) and the only difference is the datapoints given. To give some variety, I tried creating an additional datapoint that was `undef' but the results were the same. Is this an issue with the module?

perl 5.8.3
GD 1.18
GD::Text 0.86
GD::Graph 1.43
libgd 1.8.4-11

Thanks in advance

Replies are listed 'Best First'.
Re: GD::Graph issue with similar datapoints
by ViceRaid (Chaplain) on Feb 04, 2004 at 16:20 UTC

    Hi

    Looks like a bug, unfortunately; it only seems to get tripped if you've got a data series with all the same values which are all negative numbers.

    No promises but you might try inserting the following after you use the packages, but before you write your main code. It redefines the method with the bug in it to a version that may work better. You'll see from the original comments that the author (mjv) has already guessed it's going to happen, so there may be some regression problems with applying it.

    use GD::Graph::lines; package GD::Graph::axestype; # this is the function which I think is buggy sub _best_ends { my ($min, $max, $n_ref, $min_range) = @_; # Adjust for the min range if need be ($min, $max) = _fit_vals_range($min, $max, $min_range); my ($best_min, $best_max, $best_num) = ($min, $max, 1); # mgjv - Sometimes, for odd values, and only one data set, this wi +ll be # necessary _after_ the previous step, not before. Data sets of on +e # long with negative values were causing infinite loops later on. # THE BUG'S AROUND HERE - I swapped this line and the one after # Check that min and max are not the same, and not 0 ($min, $max) = ($min) ? ($min * 0.5, $min * 1.5) : (-1,1) if ($max == $min); ($min, $max) = ($max, $min) if ($min > $max); my @n = ref($n_ref) ? @$n_ref : $n_ref; if (@n <= 0) { @n = (3..6); } else { @n = map { ref($_) ? @$_ : /(\d+)/i ? $1 : (3..6) } @n; } my $best_fit = 1e30; my $range = $max - $min; # create array of interval sizes my $s = 1; while ($s < $range) { $s *= 10 } while ($s > $range) { $s /= 10 } my @step = map {$_ * $s} (0.2, 0.5, 1, 2, 5); for my $n (@n) { # Try all numbers of intervals next if ($n < 1); for my $step (@step) { next if ($n != 1) && ($step < $range/$n); # $step too smal +l my ($nice_min, $nice_max, $fit) = _fit_interval($min, $max, $n, $step); next if $best_fit <= $fit; $best_min = $nice_min; $best_max = $nice_max; $best_fit = $fit; $best_num = $n; } } return ($best_min, $best_max, $best_num) } package main; # now continue ...

    As I say, I haven't tested it extensively, and it might break other stuff, but it might just work for you. You might also want to see about setting the 'y_min_value' and 'y_max_value' parameters explicitly.

    cheers
    ViceRaid

        OK, but really, really, don't let it put you off. It's unlucky to hit a bug, but GD::Graph is a very good package. I first used it several years back, and have just had cause to use it again (financial data ... yawn ...) and I get the feel that it's been substantially improved from what was already a very useful package. I've introduced it alongside a (closed-source) Java charting tool, and the speed and ease of getting very good-looking charts out of it quickly made me feel warm and happy about Perl.

        cheers
        ViceRaid

Re: GD::Graph issue with similar datapoints
by zentara (Cardinal) on Feb 04, 2004 at 16:38 UTC
    I learned one thing about GD. You need to get a "matching set" of Perl version, GD c libs, and GD perl modules. First I would go back to Perl5.8.2 or maybe even Perl5.8.0. Arn't the odd number releases to be considered "just for testing"?

    Anyways, my point is, you may be getting ahead of the developers, and so you are seeing this "bug".

    I ran into a similar situation with the "logo" option of GD::Graph.

      Arn't the odd number releases to be considered "just for testing"?

      Yes, but 5.8.3 is not an odd number (5.8.3 is a "maintenance" release, production perl). 5.9.0 is an odd number(5.9.0 is a development version) ====> http://www.cpan.org/src/

      MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
      I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
      ** The third rule of perl club is a statement of fact: pod is sexy.

      Arn't the odd number releases to be considered "just for testing"?

      Just to make explicit what PodMaster already hinted at, it's the middle digit of the version number that's odd or even depending on unstable or stable release. So anything in the 5.8.x series is allegedly stable.