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

Omshanti

I have a query related to the plotting of data through GD::Graph.

I have set the y_max_value, which defines the y axis scale of the graph in question to the value of 2.

This graph or should I say these graphs are being rendered dynamically through a CGI script on a webpage. For most of the data sets the graphs plot the data beautifully. Alas, for some, because some of the data points being above 2, the line is rendered above the y_max_value. Here is the code for the graph:

my @logConc; my @data; my @forGraph = (\@logConc,\@data); #end debug my $graph = GD::Graph::lines->new(500,300); $graph->set( x_label => 'Loged stuff', y_label => 'Intensity', title => "Plot of $cell_name (row $plateRow)", line_width => 1, legend_spacing => 5, x_tick_number => 'auto', box_axis => 0, y_min_value => 0, y_max_value => 2, transparent => 0 ) or die $graph->error; $graph->set_legend($cell_line_name); my $format = $graph->export_format; print header("image/$format"); binmode STDOUT; print $graph->plot(\@forGraph)->$format();

@logConc are the X values and @data are the values to be plotted.

Is there anyway for me to hide the plotted line above a certain threshold?

Namaste

Djodja

  • Comment on Hide plotted data that exceeds y_max_value in graph produced by GD::Graph::Lines
  • Download Code

Replies are listed 'Best First'.
Re: Hide plotted data that exceeds y_max_value in graph produced by GD::Graph::Lines
by zentara (Cardinal) on Feb 16, 2010 at 17:36 UTC
    GD graphs are not very flexible, but you could come up with some hack to fix the problem. For instance, how about looping thru the data points and set any value greater than y_max to y_max, or even to zero.

    Then do the plot.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku
Re: Hide plotted data that exceeds y_max_value in graph produced by GD::Graph::Lines
by Illuminatus (Curate) on Feb 16, 2010 at 20:30 UTC
    Well, first of all, wouldn't you want to know just how much above 2 the value really is?

    One option, not elegant, would be to make use of the y_number_format method. I believe you can return strings here. You supply a function. In this case, if the number is between y_min and y_max, print the number. If it is above y_max print "above 2".

      Thank you for your replies

      I will address both suggestions on this reply as they seem to be pretty much the same.

      * Well, first of all, wouldn't you want to know just how much above 2 the value really is?

      I do know what the value is because I have a table with those values along side the graph. But the main purpose of the graph is for my researchers to be able to compare different sets of values within the same scale.

      * GD graphs are not very flexible, but you could come up with some hack to fix the problem. For instance, how about looping thru the data points and set any value greater than y_max to y_max, or even to zero. Then do the plot.
      * One option, not elegant, would be to make use of the y_number_format method. I believe you can return strings here. You supply a function. In this case, if the number is between y_min and y_max, print the number. If it is above y_max print "above 2".

      These are not the solutions. I need the value to be plotted correctly so that slope of the curve is as it should be. If I assign any data point value that is greater then y_max_value to y_max_value, the curve will be completely diferent.

      What I really need is for GD::Graph to extrapolate and not really represent where the data point should be plotted. One solution would be to get rid of the graph title and draw a white rectangle above the top margin of the graph. Although not pretty, this would work.

      Isn't there a method in GD::Graph that would make the plotting of the curve dependent on the y_max_value?

      Once again, thank you for your replies

      May Perl be with you

      djodja

        What I really need is for GD::Graph to extrapolate and not really represent where the data point should be plotted.

        What do you mean by that?

        1. Do you want GD::Graph to simply omit any point outside the limits you specify?

          If so, should it connect the previous point directly to next?

        2. Or, do you want the graph drawn in full, but with any points or line sections that would go above or below the Y scale clipped?

          If so, one way to tackle this is two plot two graphs. Each with the same options, but one with null data ([[0],[0]]). You then blit (copy) that section of the full graph over the blank graph and print that.

          It's easier to demonstrate than describe:

          #! perl -slw use strict; use GD::Graph::lines; my @logConc = 1 .. 50; my @data = map{ -3 + rand( 6 ) } 1 .. 50; my @graphs = map GD::Graph::lines->new(500,300, 1), 1..2; for ( @graphs ) { $_->set( x_label => 'Logged stuff', y_label => 'Intensity', title => "Plot of stuff", line_width => 1, legend_spacing => 5, x_tick_number => 'auto', box_axis => 0, y_min_value => -2, y_max_value => 2, transparent => 0 ) or die $_->error; $_->set_legend('legend'); } ## Draw the full graph my $gd1 = $graphs[ 0 ]->plot( [ \@logConc, \@data ] ) or die $graphs[0]->error; ## Draw another with the same size and options, but null data. my $gd2 = $graphs[ 1 ]->plot([[0],[0]]); ## Copy the relevant portion of the full graph over the empty one $gd2->copy( $gd1, 0, 20, 0, 20, 500, 230 ); ## And display the latter. open PNG, '>:raw', 'junk.png'; print PNG $gd2->png(); close PNG; system 'junk.png';

          In theory, you could use just one graph by plotting an empty dataset, getting the gd object, setting the clip region and then plotting again with the real dataset. Unfortunately, the plots don't align correctly ;(


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Hide plotted data that exceeds y_max_value in graph produced by GD::Graph::Lines
by zentara (Cardinal) on Feb 17, 2010 at 13:46 UTC
    These are not the solutions. I need the value to be plotted correctly

    Another possibility is to plot your data, then crop it off.... meaning take only say the lower 640 pixels of the graph and discard the rest. That would maintain slope, keep the base axis and legend in line. The overshot points would not be visible, but the slope leading to it would be.... in waveform analysis it's called "clipping". I'm sure GD does cropping, google for "perl GD crop"

    Isn't there a method in GD::Graph that would make the plotting of the curve dependent on the y_max_value?

    Yeah, you would need to scale your data. Loop thru your data before plotting and detect the highest value, then scale everthing accordingly.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku