http://www.perlmonks.org?node_id=1042893


in reply to Re^5: Is this the correct structure?
in thread Is this the correct structure?

I am almost there with Chart::Gnuplot.
One question still remains to be answered...
In the final step, the:
$chart->plot2d($h1, $h2, $h3...)

where $h1, $h2, $h3 etc are the various datasets created with Chart::Gnuplot::DataSet->new, how can I pass the names ($h1, $h2 etc) if I have them in an array?
My final version of the code so far is:
#!/usr/bin/perl use Chart::Gnuplot; #one must specify FILENAME to get data from (tab-delimited), a name fo +r the output file, a type for output file (e.g. pdf, png, eps) and a +plot title ($infile, $title, $type, $plot_title) = @ARGV; $outfile = $title.'.'.$type; #add or remove colours accordingly @colour_array = ("lblue", "brown", "blue", "lred", "lgreen", "yellow", + "green", "red", "purple", "orange", "pink", "dyellow"); @data; $counter; open IN, "$infile" or die $!; $label_line = <IN>; chomp $label_line; #find the labels data (for n +aming the colours in the stacked bars) @split_labels = split(/\t/, $label_line); while(<IN>) { chomp; $counter = 0; for (split/\t/,$_) { push @{$data[$counter++]}, $_; } } close IN; #x-axis labels is the row #0 in the AoA @data @x = @{$data[0]}; $total_y = @data-1; #find how many y rows we have => how many colou +rs we need (-1 because #0 is x-axis) @pick_colours = @colour_array[ 0 .. $total_y - 1 ]; # Initiate the chart object $chart = Chart::Gnuplot->new( output => $outfile, title => $title, xlabel => { text => 'Method', color => 'black', offset => "-1", font => 'Times-Roman, 20' }, ylabel => { text => $plot_title, color => 'black', offset => -1, font => 'Times-Roman, 20' }, yrange => [0, '*'], xtics => { rotate => '-270', font => 'Times-Roman, 15' }, ytics => { font => 'Times-Roman, 15' }, bg => { color => 'white', density => 0.2, }, plotbg => 'white', legend => {position => 'outside bottom'}, border => { sides => 'bottom, left', linetype => 3, width => 2, color => 'black', }, "style histogram" => 'rowstacked' ); #all the rest rows in @data are used for creating the histogram bars #create object foreach series of data (column in excel) $counter_objects=0; @all_vars=(); for $y ( 1 .. $#data ) { $legend_name = $split_labels[$y]; #get the name for the legend, + e.g 1TM, 2TM, >2TM @tmp_y = @{$data[$y]}; #create temp array $counter_objects++; $myvar.= '$h'."$counter_objects".", "; push @all_vars, $myvar; ${h."$counter_objects"} = Chart::Gnuplot::DataSet->new ( xdata => \@x, ydata => \@tmp_y, title => "$legend_name", fill => {density => 0.2}, style => "histograms", ); } $wanted = substr ($string_of_vars,0, -2); $chart->plot2d(\@all_vars);

but in the last step, it complaints, because:
Not a HASH reference at /usr/local/share/perl/5.14.2/Chart/Gnuplot.pm

Replies are listed 'Best First'.
Re^7: Is this the correct structure?
by poj (Abbot) on Jul 06, 2013 at 13:03 UTC
    You just need to create an array of datasets. Push comes after the ->new.
    #$myvar.= '$h'."$counter_objects".", "; #push @all_vars, $myvar; #${h."$counter_objects"} = Chart::Gnuplot::DataSet->new my $ds = Chart::Gnuplot::DataSet->new( xdata => \@x, ydata => \@tmp_y, title => "$legend_name", fill => {density => 0.2}, style => "histograms", ); push @all_vars, $ds; } $chart->plot2d(@all_vars); # no \
    poj
      Again dissapointment...
      I don't really get it though!! The code executes perfectly, yet I do not get a stacked bar which adds up to 100, as it should based on the input file... In some methods it even stays as low as maybe 20, for some strange reason!
      #!/usr/bin/perl use Chart::Gnuplot; #one must specify FILENAME to get data from (tab-delimited), a name fo +r the output file, a type for output file (e.g. pdf, png, eps) and a +plot title ($infile, $title, $type, $plot_title) = @ARGV; $outfile = $plot_title.'.'.$type; #add or remove colours accordingly @colour_array = ("#00308F", "#004225", "#480607", "#AF002A", "#008000" +, "#E25822", "#3B444B", "#7C0A02", "#848482", "#563C5C"); @data; $counter; open IN, "$infile" or die $!; $label_line = <IN>; chomp $label_line; #find the labels data (for n +aming the colours in the stacked bars) @split_labels = split(/\t/, $label_line); while(<IN>) { chomp; $counter = 0; for (split/\t/,$_) { push @{$data[$counter++]}, $_; } } close IN; #x-axis labels is the row #0 in the AoA @data @x = @{$data[0]}; $total_y = @data-1; #find how many y rows we have => how many colou +rs we need (-1 because #0 is x-axis) @pick_colours = @colour_array[ 0 .. $total_y - 1 ]; # Initiate the chart object $chart = Chart::Gnuplot->new( output => $outfile, title => $title, xlabel => { text => 'Method', color => 'black', offset => "-1", font => 'Times-Roman, 20' }, ylabel => { text => 'Performance', color => 'black', offset => -1, font => 'Times-Roman, 20' }, yrange => [0, '*'], xtics => { rotate => '-270', font => 'Times-Roman, 15' }, ytics => { font => 'Times-Roman, 15' }, bg => { color => 'white', density => 0.2, }, plotbg => 'white', legend => {position => 'outside bottom'}, border => { sides => 'bottom, left', linetype => 3, width => 2, color => 'black', }, "style histogram" => 'rowstacked' ); #all the rest rows in @data are used for creating the histogram bars #create object foreach series of data (column in excel) @all_vars=(); for $y ( 1 .. $#data ) { $legend_name = $split_labels[$y]; #get the name for the legend, + e.g 1TM, 2TM, >2TM @tmp_y = @{$data[$y]}; #create temp array $ds = Chart::Gnuplot::DataSet->new( xdata => \@x, ydata => \@tmp_y, title => "$legend_name", fill => {density => 0.2}, style => "histograms", color => "$pick_colours[$y-1]" ); push @all_vars, $ds; } $chart->plot2d(@all_vars);

      The code with the suggestions/corrections of the kind monks produces no errors, BUT, if you try it on the real example, which is the following dataset:
      METHOD 0TM 1TM 2TM >2TM method1 3 68 18 10 method2 3 80 10 6 method3 3 87 9 1 method4 5 83 9 3 method5 6 75 15 4 method6 14 77 6 3 method7 12 82 2 3 method8 9 84 3 3 method9 13 68 16 3 method10 5 65 20 9 method11 9 64 20 7 method12 5 68 18 9 method13 6 82 9 2 method14 11 79 8 2 method15 6 69 20 5 method16 5 80 11 3 method17 1 68 17 14

      using the command:
      perl script.pl datasets EVALUATION png MYIMAGE

      it creates a really awful graph!!!!!

        You have 2 problems. First the data array need to be transposed to create 4 rows with 17 columns

        while(<IN>){ chomp; my @cols = split/\s+/,$_; for my $ix (0..$#cols){ push @{$data[$ix]}, $cols[$ix]; } }

        and second, in the creation of the dataset use

        ydata => [ @{$data[$y]} ],
        otherwise you create a reference to the same data each time

        poj