如何将我的数据重新排列为GD :: Graph的(x,y)坐标?

时间:2009-04-03 15:36:17

标签: perl plot gd-graph

我正在编写一个从用户接收输入文件的程序。该文件中包含大量数字,我将读取文件中的数字,并使用GD::Graph根据这些数字创建一个图。

文件的第一行是X轴,文件的第二行是对应于X轴的Y值和第三行,第四行,......等等例如:

1 2 3 4 5 
2 4 5 10 14
5 6 8 12 13

所以在上面,第一行是x轴,第二行是对应于xaxis的y值,因此这将获得10个点。 (1,2)(1,5)(2,4)(2,6)......(4,10)(4,12)(5,14)(5,13)

我计划读取数组的每一行,然后在空格或制表符上拆分行并将值存储在数组中。因此,数组1将具有x轴,array2将具有y轴,但是我应该如何在数组中存储第3,第4,第5 ......等行以使它们变为(x,y)?

此外,如何找到第一行和第二行(2个数组)的最大值,以便为X轴和Y轴创建限制?

3 个答案:

答案 0 :(得分:2)

不是您问题的答案,但不要错过GD::Graph::Data

除非您确定,每行的第一行和最后一行是最小/最大的,否则您需要使用List::Utilmin()和{{1}之类的内容}}


我真的不明白你的意思“文件的第一行是X轴,文件的第二行是Y轴,第三行,第四行,......等是与X轴对应的点。”

答案 1 :(得分:1)

您可以随时增加x和y阵列。

#!/usr/bin/perl

use Data::Dumper;
use warnings;
use strict;

my @xs = ();
my @ys = ();
my $expecting_xs = 1;
my $last_xs_count;

while(<>) {
  chomp;
  my @values = split(/\s+/);
  if($expecting_xs) {
    push(@xs, @values);
    $last_xs_count = @values;
    $expecting_xs = 0;
  } else {
    if(@values != $last_xs_count) {
      die "Count mismatch";
    } 
    push(@ys, @values);
    $expecting_xs = 1;
  }
}

if(!$expecting_xs) {
  die("Odd number of lines");
}

my($xmin, $xmax) = extremes(@xs);
my($ymin, $ymax) = extremes(@ys);

print "xmin: $xmin xmax: $xmax ymin: $ymin ymax: $ymax\n";
print Dumper(\@xs), Dumper(\@ys);

sub extremes {
  my(@values) = @_;
  return undef unless @values;
  my $min = shift(@values);
  my $max = $min;
  for my $value (@values) {
    $max = $value if $value > $max;
    $min = $value if $value < $min;
  }
  return $min, $max;
}

答案 2 :(得分:0)

哎呀,误读了这个问题,你想要AoAoH或AoH,这取决于第一行之后的每一行是代表一条线还是只是要分别绘制的点。如果文件中的每一行都成为图中的一行,我就会这样写它:

#!/usr/bin/perl

use strict;
use warnings;
use List::Util qw/min max/;

my @x_points         = split " ", scalar <>; #read in the x axis labels
my ($x_min, $x_max)  = (sort { $a <=> $b } @x_points)[0,-1];
my ($y_min, $y_max)  = (0, 0);

#lines is an AoAoH, first layer are the lines to be drawn
#second layer is a list of coords
#third layer are the x and y coords
my @lines;
while (<>) {
    my @y_points = split;
    #if the two arrays are not the same size, we have a problem
    die "invalid file\n" unless @y_points == @x_points;

    $y_min = max($y_min, @y_points);
    $y_max = min($y_max, @y_points);

    push @lines, [ 
        map { { x => $x_points[$_], y => $y_points[$_] } }  
    0 .. $#x_points 
    ];
}

use Data::Dumper;

print "x min and max $x_min $x_max\n",
      "y min and max $y_min $y_max\n",
      "data:\n",
      Dumper(\@lines);

my $i;
for my $line (@lines) {
    $i++;
    print "line $i is made up of points: ",
        (map { "($_->{x}, $_->{y}) " } @$line), "\n";
}

如果它们只是要绘制的点,那么我将如何处理它:

#!/usr/bin/perl

use strict;
use warnings;
use List::Util qw/min max/;

my @x_points         = split " ", scalar <>; #read in the x axis labels
my ($x_min, $x_max)  = (sort { $a <=> $b } @x_points)[0,-1];
my ($y_min, $y_max)  = (0, 0);

#lines is an AoAoH, first layer are the lines to be drawn
#second layer is a list of coords
#third layer are the x and y coords
my @points;
while (<>) {
    my @y_points = split;
    #if the two arrays are not the same size, we have a problem
    die "invalid file\n" unless @y_points == @x_points;

    $y_min = max($y_min, @y_points);
    $y_max = min($y_max, @y_points);

    push @points,
        map { { x => $x_points[$_], y => $y_points[$_] } }
        0 .. $#x_points;
}

use Data::Dumper;

print "x min and max $x_min $x_max\n",
      "y min and max $y_min $y_max\n",
      "data:\n",
      Dumper(\@points);

print "Here are the points: ", 
    (map { "($_->{x}, $_->{y}) " } @points), "\n";