5

我有每个学生的数据,例如

    Student Name         Score
    Jack                  89
    Jill                  70
    Sandy                 40

现在我正在尝试使用 GD::Graph::Bar 将这些绘制在条形图中,但由于我对 perl 和模块还很陌生,我发现我可以手动将图表中的所有 X 和 Y 值声明为被绘制。

但是由于我不知道每个学生的姓名和分数(从文本文件中提取),我希望能够自动执行这些值,

我在想哈希键和值是一个好方法。所以我把所有东西都放在了一个哈希表中,%hash(student name)=(score)

谁能帮我把它画成条形图或指导我?或者你会推荐一种不同的方法吗?

谢谢

“更新

这是我可以通过输入学生姓名手动绘制图表的部分。

 my $graph = GD::Graph::bars->new(800, 800);

   @data = ( 
      ["Jack","Jill"],
      ['30','50'],
        );

     $graph->set( 
        x_label           => 'Students',
        y_label           => 'Scores',
        title             => 'Student Vs. Scores',
       y_max_value       => 60,
       y_tick_number     => 8,
       y_label_skip      => 2 
      ) or die $graph->error;


    my $gd = $graph->plot(\@data) or die $graph->error;

    open(IMG, '>file.png') or die $!;
     binmode IMG;
     print IMG $gd->png;
4

3 回答 3

3

假设您的数据文件如下,使用制表符分隔符。

Student Name         Score
Jack                  89
Jill                  70
Sandy                 40

你可以做这样的事情,将你的x轴和y轴值从你的数据文件推送到数组。

use strict;
use warnings;
use CGI qw( :standard );
use GD::Graph::bars;

open my $fh, '<', 'data.txt' or die $!;

my (@x, @y);
while (<$fh>) {
   next if $. == 1;            # skip header line
   push @x, (split /\t/)[0];   # push 'Student Names' into @x array
   push @y, (split /\t/)[1];   # push 'Score' into @y array
}
close $fh;

my $graph = GD::Graph::bars->new(800, 800);

$graph->set( 
             x_label => 'Students',
             y_label => 'Scores',
             title   => 'Student Vs. Scores',
) or warn $graph->error;

my @data = (\@x, \@y);
$graph->plot(\@data) or die $graph->error();

print header(-type=>'image/jpeg'), $graph->gd->jpeg;

举个例子: 在此处输入图像描述

如果您想使用多个y轴值,假设您有另一个制表符分隔列,例如Score2,您可以轻松地执行类似的操作。

my (@x, @y, @y2);
while (<$fh>) {
   next if $. == 1;
   push @x, (split /\t/)[0];
   push @y, (split /\t/)[1];
   push @y2, (split /\t/)[2];
}

并将您的@data数组更改为:

my @data = (\@x, \@y, \@y2);

你的结果将是:在此处输入图像描述

于 2013-08-09T16:53:45.163 回答
1

根据文档,您需要将数组数组传递给plotGD::Graph::bars 的方法。听起来您已经有一个哈希,因此您需要将其转换为数组数组。有很多方法可以做到这一点,但这里有一个例子:

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my %hash = (
    Larry => 15,
    Curly => 16,
    Moe   => 20
);

my (@names, @scores);
while (my ($name, $score) = each %hash) {
    push @names, $name;
    push @scores, $score;
}

my @data = (\@names, \@scores);

print Dumper(\@data);

# $VAR1 = [ 
#           [ 
#             'Moe',
#             'Curly',
#             'Larry'
#           ],
#           [ 
#             20,
#             16,
#             15
#           ]
#        ];

不管你怎么做,确保你保留内部数组中的顺序。

于 2013-08-09T16:43:36.803 回答
1

我改编了GD::Graph 中示例目录中的代码:

use warnings;
use strict;
use GD::Graph::bars;
use GD::Graph::Data;

my %students = (
    Jack    => 89,
    Jill    => 70,
    Sandy   => 40,
);

my @scores;
my @names;
for (keys %students) {
    push @names, $_;
    push @scores, $students{$_};
}

my $data = GD::Graph::Data->new([
    [@names],
    [@scores],
]) or die GD::Graph::Data->error;

my $my_graph = GD::Graph::bars->new();
$my_graph->set(
    x_label         => 'Name',
    y_label         => 'Score',
    title           => 'A Simple Bar Chart',
) or warn $my_graph->error;
$my_graph->plot($data) or die $my_graph->error();
save_chart($my_graph, 'graph');

sub save_chart {
    my $chart = shift or die "Need a chart!";
    my $name = shift or die "Need a name!";
    local(*OUT);

    my $ext = $chart->export_format;

    open(OUT, ">$name.$ext") or
        die "Cannot open $name.$ext for write: $!";
    binmode OUT;
    print OUT $chart->gd->$ext();
    close OUT;
}
于 2013-08-09T16:52:00.033 回答