为啥 Perl 的 GD::Graph 抱怨“无效数据集”?
Posted
技术标签:
【中文标题】为啥 Perl 的 GD::Graph 抱怨“无效数据集”?【英文标题】:Why is Perl's GD::Graph complaining about "Invalid data set"?为什么 Perl 的 GD::Graph 抱怨“无效数据集”? 【发布时间】:2009-04-06 08:46:03 【问题描述】:我正在用 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;
【问题讨论】:
我将注释添加到您标记为粗体的行中(但没有显示为粗体,因为它被格式化为代码)。但是,我认为您可能标记了错误的行。我本来预计该错误与 ->plot. 一致 【参考方案1】:我认为你分配@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::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) ]
);
【讨论】:
【参考方案2】:请use strict
和use warnings
。如果您使用这些 pragma,您在此代码中遇到的许多麻烦事都会被标记出来。
您还花费了大量精力来追加到数组的末尾。您可以使用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;
另外,看看perldsc
和perlreftut
他们有很好的例子来说明如何使用引用和嵌套数据结构。
【讨论】:
【参考方案3】: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;
【讨论】:
【参考方案4】:我不太确定我在看什么,但我突然想到一件事:您正在将数组初始化为哈希引用:
hektor ~ $ perl -e '@sizearray = ; print @sizearray, "\n"'
HASH(0x8031c0)
如果你想要的只是一个空数组,你可以简单地说:
my @sizearray;
如果你想明确它是新的和空的,你需要括号;见下文。 (然而,正如 Brad 在他的评论中所说,这是多余的。您可能应该习惯于查看和编写更简单的版本。)
my @sizearray = ();
数组存储有序列表,列表放在括号中。请参阅perldoc perldata
了解更多信息。
【讨论】:
my @sizearray;
和我的@sizearray = ();
一模一样
我知道,但有些人似乎喜欢@sizearray = ();
的视觉提醒,也许这只是他们对其他语言的遗产,我自己不这样做。我的意思是,如果他坚持, () 不会像 那样破坏事情。不过我会记下。以上是关于为啥 Perl 的 GD::Graph 抱怨“无效数据集”?的主要内容,如果未能解决你的问题,请参考以下文章
为啥即使 CPAN 说 GD::Graph::pie 已安装并且是最新的,“使用 GD::Graph::pie;”也会失败?