Comment puis-je réorganiser mes données soient (x, y) les coordonnées de GD :: Graph?
Question
Je suis en train d'écrire un programme qui prend dans un fichier d'entrée de l'utilisateur. Le fichier a tas de chiffres en elle et je vais lire les numéros dans le fichier et créer un terrain basé sur les chiffres à l'aide GD :: Graph .
La première ligne du fichier est l'axe X, la deuxième ligne du fichier est valeurs Y correspondant à l'axe X et troisième, quatrième, ..., etc, par exemple:
1 2 3 4 5
2 4 5 10 14
5 6 8 12 13
Ainsi, dans la ligne ci-dessus, est d'abord xaxis, deuxième valeurs est y correspondant à XAXIS si cela va chercher 10 points. (1, 2) (1, 5) (2, 4) (2, 6) .... (4,10) (4,12) (5,14) (5, 13)
je prévois à la lecture de chaque ligne de la matrice, puis le fractionnement de la ligne sur des espaces ou des languettes et la mémorisation des valeurs dans un tableau. Donc, un tableau 1 aura axe x, array2 y aura-axe, mais comment dois-je stocker 3ème, 4ème, 5ème, ..., etc lignes dans un tableau afin qu'ils deviennent (x, y)?
De plus, comment puis-je trouver la plus grande valeur pour les première et deuxième lignes (2 tableaux) donc je peux créer une limite pour mes axes X et Y?
La solution
Whoops, mal interprété la question, vous voulez soit un AoAoH ou un AoH, selon que chaque ligne après la première représente une ligne ou tous les points sont juste à tracer respectivement. Voici comment je l'écrirais si chaque ligne dans le fichier devait devenir une ligne dans le graphique:
#!/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";
}
Et voici comment je débrouille si elles sont juste des points à ploted:
#!/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";
Autres conseils
Pas vraiment une réponse à votre question, mais ne manquez pas GD: :. Graphique :: données
Sauf si vous êtes vous que le premier et le dernier sur chaque ligne est le plus petit / plus grand que vous aurez besoin d'utiliser quelque chose comme Liste :: Util de min()
et max()
.
Je ne comprends pas vraiment ce que vous entendez par « La première ligne du fichier est l'axe X, la deuxième ligne du fichier est l'axe Y et troisième, quatrième, ..., etc sont les points correspondants à l'axe X. »
Vous pouvez développer vos tableaux de x et y comme vous allez.
#!/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;
}