为什么 Perl 的 GD::Graph 抱怨“无效数据集”?

发布于 2024-07-16 06:16:46 字数 1612 浏览 3 评论 0原文

我正在为我的作业用 Perl 编写一个小程序,而且我是 Perl 新手。

我编写的代码为我提供了与我需要的完全相同的值,但在创建条形图时出现此错误。

Invalid data set: 0 at line 67

下面的代码中第 67 行被注释了。

存储在 x 轴中的值是:

40 44 48 52 64 76 83 104 105 148 149 249 431 665 805 1420 1500 

y_axis 是:

16 1  1 6 1 1 1 1 1 1 1 1 1 1 1 2 5 

这是我的代码:

use GD::Graph::bars;

open(CHECKBOOK,"c:\\Perl\\bin\\ip_packet_trace1.txt");

my $counter = -1;
my @sizearray = {};
while ($record = <CHECKBOOK>) {
    @array = split(/\t/,$record);
    $counter++;
    $sizearray[$counter] = $array[6];

}

$counter++;

my @array1 = sort {$a <=> $b} @sizearray;
print "$counter\n";
print "@array1\n";


my @freq = {0...0};

foreach $elem (@array1){

    my $s = $freq[$elem]+1;

    $freq[$elem] = $s;
}


my $size = @freq;
my @x_axis = {};
my @y_axis = {};

my $count2 = -1;


for($i = 1; $i < $size; $i++){

    my $elem = $freq[$i];

    if($elem  and $elem > 0  ){

        $count2++;

        $x_axis[$count2] =  $i;

        $y_axis[$count2] = $elem;
    }

}


print "@x_axis \n";
print "@y_axis \n";




my $mygraph = GD::Graph::bars->new(500, 300); # line 67

$mygraph->set(x_label     => 'Month',

y_label     => 'Number of Hits',

title       => 'Number of Hits in Each Month in 2002',

) or warn $mygraph->error;

my @data = {@x_axis,@y_axis};



my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

open(IMG, '>C:\\image\\file.gif') or die $!;

binmode IMG;

print IMG $myimage->gif;

close IMG;

I am writing a small program in Perl for my assignment and I am new to Perl.

Code that I have written provides me with exactly the same values I need, but I am getting this error while creating bar chart.

Invalid data set: 0 at line 67

Line 67 is marked with a comment in the code below.

The values stored in x-axis are:

40 44 48 52 64 76 83 104 105 148 149 249 431 665 805 1420 1500 

And y_axis are:

16 1  1 6 1 1 1 1 1 1 1 1 1 1 1 2 5 

Here's my code:

use GD::Graph::bars;

open(CHECKBOOK,"c:\\Perl\\bin\\ip_packet_trace1.txt");

my $counter = -1;
my @sizearray = {};
while ($record = <CHECKBOOK>) {
    @array = split(/\t/,$record);
    $counter++;
    $sizearray[$counter] = $array[6];

}

$counter++;

my @array1 = sort {$a <=> $b} @sizearray;
print "$counter\n";
print "@array1\n";


my @freq = {0...0};

foreach $elem (@array1){

    my $s = $freq[$elem]+1;

    $freq[$elem] = $s;
}


my $size = @freq;
my @x_axis = {};
my @y_axis = {};

my $count2 = -1;


for($i = 1; $i < $size; $i++){

    my $elem = $freq[$i];

    if($elem  and $elem > 0  ){

        $count2++;

        $x_axis[$count2] =  $i;

        $y_axis[$count2] = $elem;
    }

}


print "@x_axis \n";
print "@y_axis \n";




my $mygraph = GD::Graph::bars->new(500, 300); # line 67

$mygraph->set(x_label     => 'Month',

y_label     => 'Number of Hits',

title       => 'Number of Hits in Each Month in 2002',

) or warn $mygraph->error;

my @data = {@x_axis,@y_axis};



my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

open(IMG, '>C:\\image\\file.gif') or die $!;

binmode IMG;

print IMG $myimage->gif;

close IMG;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

享受孤独 2024-07-23 06:16:46

我认为您对 @data 的分配可能是罪魁祸首。

my @data = {@x_axis,@y_axis};

这将创建一个包含一个元素的数组。 该元素是一个散列。 GD::Graph 文档显示您需要一组数组。 正如 daotoad 所说, Data::Dumper 派上用场了。 尝试以下操作:

use Data::Dumper;
my @x_axis = 1...100;
my @y_axis = "a"..."z";
my @data = {@x_axis,@y_axis};
warn Dumper(\@data);

您可以查看数据的解释方式,并发现它与 GD::图示例

@data = ( 
    ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"],
    [    1,    2,    5,    6,    3,  1.5,    1,     3,     4],
    [ sort { $a <=> $b } (1, 2, 5, 6, 3, 1.5, 1, 3, 4) ]
  );

I think your assignment of @data is probably to blame.

my @data = {@x_axis,@y_axis};

This creates an array with one element. That one element is a hash. The GD::Graph documentation shows that you need an array of arrays. This is where, as daotoad stated, Data::Dumper comes in handy. Try out the following:

use Data::Dumper;
my @x_axis = 1...100;
my @y_axis = "a"..."z";
my @data = {@x_axis,@y_axis};
warn Dumper(\@data);

You can see how the data is being interpreted, and see that it is not the same as the GD::Graph example:

@data = ( 
    ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"],
    [    1,    2,    5,    6,    3,  1.5,    1,     3,     4],
    [ sort { $a <=> $b } (1, 2, 5, 6, 3, 1.5, 1, 3, 4) ]
  );
纵山崖 2024-07-23 06:16:46

使用严格使用警告。 如果您使用这些编译指示,您在这段代码中遇到的许多麻烦的事情都会被标记出来。

您还花费了大量的精力来附加到数组的末尾。 您可以使用 push 来执行此操作,而无需知道最后一项的索引。 像这样使用push可以让你的代码变得相当简单。

使用 () 创建一个空数组(实际上是列表)。 使用 [] 进行数组引用。 使用 {} 进行哈希引用。 您已经在很多地方使用了哈希引用。

最好使用词法文件句柄而不是全局文件句柄。 使用全局文件句柄就是使用不必要的全局变量,这是自找麻烦。 另请检查对 open 的调用是否成功。

open( my $fh, '<', 'path/to/file)
    or die "Unable to open data file - $!\n";

当您使用数据结构时,Data::Dumper 是一个有用的模块,可以查看正在发生的情况。

use Data::Dumper;

my $foo = {
  bar => [ 0..5],
  baz => { a..z },
};

my @qux = ( [qw/a b c d/], [0..5] );

print Dumper $foo;
print Dumper \@qux;

另外,请查看 perldscperlreftut,它们提供了有关如何使用引用和嵌套数据结构的很好的示例。

Please use strict and use warnings. Many of the troublesome things you have going on in this code will be flagged for you if you use these pragmas.

You are also expending a lot of effort to append to the end of your arrays. You can use push to do this without knowing the index of the last item. Using push like this will let you simplify your code quite a bit.

Use () to make an empty array (well list really). Use [] to make an array reference. use {} to make a hash reference. You've been using hash refs in a number of places.

It is also best to use lexical filehandles instead of global filehandles. Using global file handles is using unnecessary global variables, which is asking for trouble. Also check for success on your calls to open.

open( my $fh, '<', 'path/to/file)
    or die "Unable to open data file - $!\n";

When you are working with data structures, Data::Dumper is a useful module to see what's going on.

use Data::Dumper;

my $foo = {
  bar => [ 0..5],
  baz => { a..z },
};

my @qux = ( [qw/a b c d/], [0..5] );

print Dumper $foo;
print Dumper \@qux;

Also, take a look at perldsc and perlreftut they have good examples of how to work with references and nested data structures.

枉心 2024-07-23 06:16:46

K. 我测试并修改了你的代码。 下面的代码有效。 每个人都提到的数组部分很重要,但不是你唯一的问题。 cpan 中的示例是一个匿名数组,因此您只需传递 2 个对 @data 的引用,而不是传递 @data 2 个数组。

#!/usr/bin/perl
#
use GD::Graph::bars;

my $size = @freq;
my @x_axis = qw(40 44 48 52 64 76 83 104 105 148 149 249 431 665 805 1420 1500);
my @y_axis = qw(16 1  1 6 1 1 1 1 1 1 1 1 1 1 1 2 5);

my $mygraph = GD::Graph::bars->new(500, 300); # line 67
$mygraph->set(x_label     => 'Month',
            y_label     => 'Number of Hits',
            title       => 'Number of Hits in Each Month in 2002',
) or warn $mygraph->error;
my @data = (\@x_axis,\@y_axis); # the important part.
my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

open(IMG, '>helping_graph.gif') or die $!;
binmode IMG;
print IMG $myimage->gif;
close IMG;

K. I tested and altered you code. The below code works. The array part that everyone mentioned was important, but not your only problem. The example in cpan, was of an anonymous array, so instead of passing @data 2 arrays, you just needed to pass 2 references to @data.

#!/usr/bin/perl
#
use GD::Graph::bars;

my $size = @freq;
my @x_axis = qw(40 44 48 52 64 76 83 104 105 148 149 249 431 665 805 1420 1500);
my @y_axis = qw(16 1  1 6 1 1 1 1 1 1 1 1 1 1 1 2 5);

my $mygraph = GD::Graph::bars->new(500, 300); # line 67
$mygraph->set(x_label     => 'Month',
            y_label     => 'Number of Hits',
            title       => 'Number of Hits in Each Month in 2002',
) or warn $mygraph->error;
my @data = (\@x_axis,\@y_axis); # the important part.
my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

open(IMG, '>helping_graph.gif') or die $!;
binmode IMG;
print IMG $myimage->gif;
close IMG;
醉酒的小男人 2024-07-23 06:16:46

我不太确定我在看什么,但有一件事突然引起我的注意:您正在将数组初始化为哈希引用:

hektor ~ $ perl -e '@sizearray = {}; print @sizearray, "\n"'
HASH(0x8031c0)

如果您想要的只是一个空数组,您可以简单地说:

my @sizearray;

如果您想使清除它是新的和空的,你需要括号; 见下文。 (然而,正如布拉德在他的评论中所说,这是多余的。您可能应该习惯查看和编写更简单的版本。)

my @sizearray = ();

数组存储有序列表,列表放在括号中。 有关更多信息,请参阅 perldoc perldata

I'm not really sure what I'm looking at, but one thing jumps out at me: you are initializing your arrays as hash references:

hektor ~ $ perl -e '@sizearray = {}; print @sizearray, "\n"'
HASH(0x8031c0)

If all you want is an empty array, you can say simply this:

my @sizearray;

If you want to make clear it's new and empty, you want parentheses; see below. (As Brad says in his comment, however, this is redundant. You should probably get used to seeing and writing the simpler version.)

my @sizearray = ();

Arrays store ordered lists and lists go in parentheses. See perldoc perldata for more.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文