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

Hi All,

I've created 32 line graphs with GD and GD::Graph that update with new data every 15 minutes. I'm pretty happy with them with a few exceptions.

One problem is with the y-axis when I have y values that include negative and positive values. I'm not setting the y_tick_number, y_label_skip, y_max_value, or y_min_value. I'm letting GD::Graph take care of that and it works well for the majority of the graphs.

The problem occurs when I have y values that range from say -0.6 to 0.4. The y ticks get labeled
0.4
0.2
-1.11022302462516e-16
-0.2
-0.4
-0.6.
I understand that the really small value is an approximation of zero and probably has something to do with rounding. However, it is unacceptable on a graph. Besides being an odd looking number, it takes up a lot of space and squishes the graph to the right.

I haven't been able to find any references to this problem. Any suggestions on how to fix it?

Thanks

Replies are listed 'Best First'.
Re: GD::Graph y-axis problem
by snax (Hermit) on Oct 02, 2003 at 14:47 UTC
    Try setting the y_number_format attribute which can either be a code reference or an sprintf format string. Using something like '%4.1f' ought to force the nearly zero number to print as zero. Check the docs for examples.
Re: GD::Graph y-axis problem
by tachyon (Chancellor) on Oct 02, 2003 at 15:09 UTC

    And here is where it all happens in axestype.pm where you can see it applying the y_number_format attrib.

    sub create_y_labels { my $self = shift; # XXX This should really be y_label_width $self->{y_label_len}[$_] = 0 for 1, 2; $self->{y_label_height}[$_] = 0 for 1, 2; for my $t (0 .. $self->{y_tick_number}) { # XXX Ugh, why did I ever do it this way? How bloody obscure. for my $axis (1 .. ($self->{two_axes} + 1)) { my $label = $self->{y_min}[$axis] + $t * ($self->{y_max}[$axis] - $self->{y_min}[$axis]) / $self->{y_tick_number}; $self->{y_values}[$axis][$t] = $label; if (defined $self->{y_number_format}) { $label = ref $self->{y_number_format} eq 'CODE' ? &{$self->{y_number_format}}($label) : sprintf($self->{y_number_format}, $label); } $self->{gdta_y_axis}->set_text($label); my $len = $self->{gdta_y_axis}->get('width'); $self->{y_labels}[$axis][$t] = $label; # TODO Allow vertical y labels $self->{y_label_len}[$axis] = $len if $len > $self->{y_label_len}[$axis]; $self->{y_label_height}[$axis] = $self->{yafh}; } } }

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: GD::Graph y-axis problem
by kryberg (Pilgrim) on Oct 02, 2003 at 15:50 UTC
    Cool - it works! Thanks for both of the comments. It worked on the first try, only problem being I got -0.0. I was able to fix that though.
    sub format { my $val = shift; my $ret; if ($val < 0.001 && $val > -0.001 ) { $ret = sprintf('%4.2f',abs($val)); } else { $ret = sprintf('%4.2f',$val); } return $ret; }