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

Hi Monks, Can someone please help me with the below requirement. I have 3 datasets and I have to plot them in a Graph and send it as an inline image in mail. It should have two Y axes. The intent is to enforce the first dataset to refer to left Y axis with certain values and the next 2 datasets to refer to right Y axis. Can someone please provide an insight of how this can be achieved. Also, the 1st dataset be plotted in bar graph and the rest two in linespoints. I can make this using only GD::Graph::Mixed. Thanks

Replies are listed 'Best First'.
Re: Plotting the data using different axes
by zentara (Cardinal) on Jun 05, 2018 at 09:31 UTC
    Hi, here is a start for you.
    #!/usr/bin/perl use warnings; use strict; use GD::Graph::mixed; #my @data = ( # ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], # [ 3, 4, 14, 30, 12, 8, 7, 20, 15], # [ 2, 8, 2, 5, 3, 1, 3, 4, 1], my @data = ( ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], [ 3, 4, 14, '', '', '', 7, 20, 15], [ '', '', '', 5, 3, 1, 3, 4, 1], # [ 5, 12, 24, 33, 19, 8, 6, 15, 21], # [ 1, 2, 5, 6, 3, 1.5, 1, 3, 4], ); #sets 3,4 will overwrite second y label my $my_graph = new GD::Graph::mixed( ); $my_graph->set( transparent => '0', x_label => 'X Label', y1_label => 'Y1 label', y2_label => 'Y2 label', title => 'Using two axes', y1_max_value => 40, y2_max_value => 8, y_tick_number => 8, y_label_skip => 2, long_ticks => 1, use_axis => [1,2,1,2], legend_placement => 'BR', x_labels_vertical => 1, x_label_position => 1/2, two_axes => 1, legend_marker_width => 100, l_margin => 10, b_margin => 10, r_margin => 20, t_margin => 10, show_values => 1, ); $my_graph->set_legend( 'X', 'XY', 'diff-X/XY', '95%XY'); #$my_graph->set_legend( 'X', 'XY'); my $gd = $my_graph->plot(\@data) or die $my_graph->error; open(IMG, ">$0.png") or die "$!\n"; binmode IMG; print IMG $gd->png; close IMG;

    I'm not really a human, but I play one on earth. ..... an animated JAPH
      If I add one more array like 5, 12, 24, 33, 19, 8, 6, 15, 21, to the @data and it has to be referring to right axis as well, how can this be achieved. I believe it has something to do with use_axes if I am not wrong. Can you please help me with this.

        GD::Graph says for "use_axis":

        If two y-axes are in use and more than two datasets are specified, set this option to an array reference containing a value of 1 or 2 (for the left and right scales respectively) for each dataset being plotted. That is, to plot three datasets with the second on a different scale than the first and third, set this to [1,2,1].

        If, as in zentara's Re: Plotting the data using different axes, your data is

        my @data = ( ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], [ 3, 4, 14, '', '', '', 7, 20, 15], [ '', '', '', 5, 3, 1, 3, 4, 1], );
        , then use_axis => [1,2] will put the [3,4,14,...] on the left axis, and the [...,5,3,1,3,4,1] on the right axis. Using use_axis => [2,1] would swap them.

        If you add another row of y data,

        my @data = ( ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], [ 3, 4, 14, '', '', '', 7, 20, 15], [ '', '', '', 5, 3, 1, 3, 4, 1], [ 5, 12, 24, 33, 19, 8, 6, 15, 21], );
        , you would have it plot on the right axis by using use_axis => [1,2,2]: this says "put the first group of y data on axis 1, the second group on axis two, and the third group on axis two.".

        If you add a fourth row

        my @data = ( ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], [ 3, 4, 14, '', '', '', 7, 20, 15], [ '', '', '', 5, 3, 1, 3, 4, 1], [ 5, 12, 24, 33, 19, 8, 6, 15, 21], [ 3, 14, 15, 9, 2, 6, 5, 3, 5], );
        , you would have it plot on the left axis by using use_axis => [1,2,2,1], which says "put the first group of y data on axis 1, the second group on axis two, and the third group on axis two, and the fourth group on axis one."

        zentara's code may have confused you, with the commented rows, and having four elements in the use_axis array, even though only two groups of y data were uncommented... but if you had just uncommented the extra rows, you could have seen which axis they ended up on, which is why I believe zentara left those commented lines available.

        edit: please use <code> tags, like <code>[ 5, 12, 24, 33, 19, 8, 6, 15, 21]</code>, so your anonymous-array examples don't get converted into links by the perlmonks rendering engine

Re: Plotting the data using different axes
by choroba (Cardinal) on Jun 05, 2018 at 09:02 UTC
    Hi Sarat1729! Could you include (samples of) the datasets in the post? Also, I don't see any GD::Graph::Mixed in CPAN. Are you sure you got the name right?

    This isn't a code writing service. What have you tried? How did it fail?

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      I tried the below code.
      my $graph = new GD::Graph::mixed( 900, 600 ); my @data = ( [ '1st', '2nd', '3rd', '4th', '5th' ], [ 3300, 2400, 2300, 1900, 2100 ], [ 500, 550, 900, 510, 400 ], [ 250, 350, 400, 710, 200 ] ); $graph->set( title => TITLE, two_axes => 1, use_axis => [1,2,2], x_label => "Day", y1_label => "Minutes", y2_label => "Hours", long_ticks => 1, y_tick_number => 8, y1_label_skip => 2, y2_label_skip => 2, bar_spacing => 40, types => [ qw(bars linespoints linespoints) ], );

      In the dataset 3300 ... 2100, should be plotted in bars using left y axis, which is working. 500 ... 400 and 250 ... 200 should be plotted in linespoints which is also working but referring to left y axis. However, my intent is, it should be plotted according to right y axis. Also, right y axis is getting plotted.

      2018-06-08 Athanasius added code tags