Wie kann ich mithilfe von Perl Diagramme mit Werten in einer CSV -Datei erstellen?

StackOverflow https://stackoverflow.com/questions/1340730

  •  20-09-2019
  •  | 
  •  

Frage

Ich bin neu dabei und brauche einen Ahnung, wie diese Aufgabe erledigt werden soll. Ich habe eine CSV -Datei mit folgenden Beispieldaten:

site,type,2009-01-01,2009-01-02,....
X,A,12,10,...
X,B,10,23,...
Y,A,20,33,...
Y,B,3,12,...

and so on....

Ich möchte ein Perl -Skript erstellen, um Daten aus der CSV -Datei (gemäß der angegebenen Benutzereingabe) zu lesen und XY -Diagramme (Scatter) zu erstellen. Nehmen wir an, ich möchte ein Diagramm für das Datum 2009-01-01 und Typ B erstellen. Der Benutzer sollte so etwas wie "2009-01-01 B" eingeben, und das Diagramm sollte mit den Werten aus der CSV-Datei erstellt werden.

Kann mir bitte jemand einen Code vorschlagen?

War es hilfreich?

Lösung

Ich muss einige eigene Streudiagramme machen, also habe ich mit dem in den anderen Antworten vorgeschlagenen Modul herumgespielt. Für meinen Geschmack die Datenpunkte produziert von GD :: Graph :: kartesianisch sind viel zu groß und das Modul bietet keine Methoden zur Steuerung dieses Parameters, daher habe ich meine Kopie von gehackt Cartesian.pm (suchen nach iconsize Wenn Sie dasselbe tun möchten).

use strict;
use warnings;
use Text::CSV;
use GD::Graph::Cartesian;

# Parse CSV file and convert the data for the
# requested $type and $date into a list of [X,Y] pairs.
my ($csv_file, $type, $date) = @ARGV;
my @xy_points;
my %i = ( X => -1, Y => -1 );
open(my $csv_fh, '<', $csv_file) or die $!;
my $parser = Text::CSV->new();
$parser->column_names( $parser->getline($csv_fh) );
while ( defined( my $hr = $parser->getline_hr($csv_fh) ) ){
    next unless $hr->{type} eq $type;
    my $xy = $hr->{site};
    $xy_points[++ $i{$xy}][$xy eq 'X' ? 0 : 1] = $hr->{$date};
}

# Make a graph.
my $graph = GD::Graph::Cartesian->new(
    width   => 400, # Image size (in pixels, not X-Y coordinates).
    height  => 400,
    borderx => 20,  # Margins (also pixels).
    bordery => 20,
    strings => [[ 20, 50, 'Graph title' ]],
    lines => [
        [ 0,0, 50,0 ], # Draw an X axis.
        [ 0,0,  0,50], # Draw a Y axis.
    ],
    points => \@xy_points, # The data.
);
open(my $png_file, '>', 'some_data.png') or die $!;
binmode $png_file;
print $png_file $graph->draw;

Andere Tipps

Beginnen Sie nicht mit Code. Beginnen Sie mit CPAN.

CSV und Streuen

Hier gehen Sie, ein Code, mit dem Sie beginnen sollen:

#!/usr/bin/perl -w
use strict;

use Text::CSV;
use GD;
use Getopt::Long;

Anstelle von GD können Sie natürlich jedes Modul verwenden, das Sie möchten.

OK, Nur für Unterhaltungszwecke:

#!/usr/bin/perl

use strict;
use warnings;

use DBI;
use List::AllUtils qw( each_array );

my $dbh = DBI->connect("DBI:CSV:f_dir=.", undef, undef, {
        RaiseError => 1, AutoCommit => 1,
    }
);

my $sth = $dbh->prepare(qq{
    SELECT d20090101 FROM test.csv WHERE type = ? and site = ?
});

$sth->execute('B', 'X');
my @x = map { $_->[0] } @{ $sth->fetchall_arrayref };

$sth->execute('B', 'Y');
my @y = map { $_->[0] } @{ $sth->fetchall_arrayref };

my @xy;

my $ea = each_array(@x, @y);
while ( my @vals = $ea->() ) {
    push @xy, \@vals;
}

my @canvas;
push @canvas, [ '|', (' ') x 40 ] for 1 .. 40;
push @canvas, [ '+', ('-') x 40 ];

for my $coord ( @xy ) {
    warn "coords=@$coord\n";
    my ($x, $y) = @$coord;
    $canvas[40 - $y]->[$x + 1] = '*';
}

print join "\n", map { join '', @$_ } @canvas;

Hinzufügen von Achsen und im Allgemeinen verbessert in Streudiagramm - Ein wirklich enttäuschendes Modul - als Übung für den Leser.

Bitte beachten Sie, dass ich immer betrügen muss, wenn es um SQL geht. Ich würde mich für ein angemessenes Schaden freuen JOIN das vermeidet das Bedürfnis nach @x, @y und each_array.

Ausgabe:

|
|
|
|            *
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|          *
|
|
+----------------------------------------
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top