【问题标题】:GD::Graph with PerlGD::Graph 与 Perl
【发布时间】:2013-08-09 15:54:28
【问题描述】:

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

    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;

【问题讨论】:

  • 到目前为止你有什么尝试?
  • 我不知道如何绘制哈希表。我被困在这一点上。
  • 刚刚添加到我的主帖中。

标签: perl graph charts


【解决方案1】:

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

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);

您的结果将是:

【讨论】:

    【解决方案2】:

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

    #!/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
    #           ]
    #        ];
    

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

    【讨论】:

    • 嘿,我刚刚实现了这个方法,它奏效了。我能够创建一个漂亮的小图表并进行相应的调整。谢谢!然而,我刚刚遇到了一个问题。我现在没有为每个学生设置一个平均值,而是为每个学生设置了两个平均值。而且我认为我不能使用具有两个值的哈希。任何意见或建议都会很棒。
    • 你可以做my %hash = ( Jack =&gt; [ 89, 90 ] );
    • 其实,我想我明白了。我将摆脱散列,添加另一个数组并将其添加到我的 @data = (\@names,\@scores,\@newarray);
    • hwnd,我也可以绘制这两个值吗?
    • 你可以绘制两个值
    【解决方案3】:

    我修改了代码from the samples directory in 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-02
      • 2017-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多