2013-08-09 12 views
5

Mam dane dla każdego ucznia, npGD :: Graph Perl

Student Name   Score 
    Jack     89 
    Jill     70 
    Sandy     40 

Teraz staram się wykreślić je na wykresie słupkowym użyciu GD :: Graph :: Bar, ale ponieważ Jestem całkiem nowy dla perla i modułów, widzę, że mogę ręcznie zadeklarować wszystkie wartości X i Y z wykresu, który ma zostać wykreślony.

Ale ponieważ nie znam nazwiska i wyniki każdego ucznia (ciągniętych z pliku tekstowego) Chcę być w stanie to zrobić wartości automatycznie

Myślałam klucze i wartości hash było dobrym podejściem. Więc umieściłem wszystko w tabeli mieszania,% hash (nazwa ucznia) = (ocena)

Czy ktoś może mi pomóc w spiskowaniu tego jako wykresu słupkowego lub prowadzić mnie? A może poleciłbyś inne podejście?

Dzięki

„Aktualizacja

To jest ta część, gdzie mogę wykreślić wykres ręcznie poprzez wpisanie nazwy studenckich.

my $graph = GD::Graph::bars->new(800, 800); 

    @data = ( 
     ["Jack","Jill"], 
     ['30','50'], 
     ); 

    $graph->set( 
     x_label   => 'Students', 
     y_label   => 'Scores', 
     title    => 'Student Vs. Scores', 
     y_max_value  => 60, 
     y_tick_number  => 8, 
     y_label_skip  => 2 
    ) or die $graph->error; 


    my $gd = $graph->plot(\@data) or die $graph->error; 

    open(IMG, '>file.png') or die $!; 
    binmode IMG; 
    print IMG $gd->png; 
+2

Co masz swój próbowałem tak daleko? – hwnd

+0

Nie wiem, jak wykreślić tabelę skrótów. I utknąłem w tym punkcie. –

+0

Pokaż kod, który masz do tworzenia wykresu bez użycia skrótu. – toolic

Odpowiedz

3

Zakładając, że plik danych jest w następujący sposób, przy użyciu ograniczników tab.

Student Name   Score 
Jack     89 
Jill     70 
Sandy     40 

Można zrobić coś takiego, spychając swoje x oś i wartości y osi z pliku danych do tablic.

use strict; 
use warnings; 
use CGI qw(:standard); 
use GD::Graph::bars; 

open my $fh, '<', 'data.txt' or die $!; 

my (@x, @y); 
while (<$fh>) { 
    next if $. == 1;   # skip header line 
    push @x, (split /\t/)[0]; # push 'Student Names' into @x array 
    push @y, (split /\t/)[1]; # push 'Score' into @y array 
} 
close $fh; 

my $graph = GD::Graph::bars->new(800, 800); 

$graph->set( 
      x_label => 'Students', 
      y_label => 'Scores', 
      title => 'Student Vs. Scores', 
) or warn $graph->error; 

my @data = (\@x, \@y); 
$graph->plot(\@data) or die $graph->error(); 

print header(-type=>'image/jpeg'), $graph->gd->jpeg; 

Podając za przykład: enter image description here

Jeśli chcą korzystać z wielu y wartości osi, przy założeniu, że masz inną kolumnę z separatora zakładka na przykład Score2, można łatwo zrobić coś takiego.

my (@x, @y, @y2); 
while (<$fh>) { 
    next if $. == 1; 
    push @x, (split /\t/)[0]; 
    push @y, (split /\t/)[1]; 
    push @y2, (split /\t/)[2]; 
} 

I zmienić tablicę do @data:

my @data = (\@x, \@y, \@y2); 

a twój wynik będzie: enter image description here

1

Według documentation, trzeba przekazać tablicę tablic do metody plot z GD :: Graph :: słupki.To brzmi jak masz już hash, więc musisz przekonwertować go na tablicę tablic.Istnieje kilka sposobów, aby to zrobić, ale oto przykład:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Data::Dumper; 

my %hash = (
    Larry => 15, 
    Curly => 16, 
    Moe => 20 
); 

my (@names, @scores); 
while (my ($name, $score) = each %hash) { 
    push @names, $name; 
    push @scores, $score; 
} 

my @data = (\@names, \@scores); 

print Dumper(\@data); 

# $VAR1 = [ 
#   [ 
#    'Moe', 
#    'Curly', 
#    'Larry' 
#   ], 
#   [ 
#    20, 
#    16, 
#    15 
#   ] 
#  ]; 

Jednak robisz to, pamiętaj o zachowaniu porządku w wewnętrznych tablicach.

+0

Hej, właśnie wdrożyłem tę metodę i zadziałało. Udało mi się stworzyć ładny mały wykres i odpowiednio go dostosować. Dziękuję Ci! Jednak napotkałem problem. Zamiast jednej średniej dla każdego ucznia, mam teraz dwie średnie dla każdego ucznia. I nie sądzę, że mogę użyć skrótu z dwiema wartościami. Wszelkie dane wejściowe lub sugestie będą świetne. –

+2

Możesz zrobić "mój% hash = (Jack => [89, 90]);' – hwnd

+0

Właściwie, myślę, że dostałem to. Po prostu pozbędę się skrótów, dodam kolejną tablicę i dodaję ją do moich @data = (\ @names, \ @ score, \ @ newarray); –

1

I dostosowany kod from the samples directory in GD::Graph:

use warnings; 
use strict; 
use GD::Graph::bars; 
use GD::Graph::Data; 

my %students = (
    Jack => 89, 
    Jill => 70, 
    Sandy => 40, 
); 

my @scores; 
my @names; 
for (keys %students) { 
    push @names, $_; 
    push @scores, $students{$_}; 
} 

my $data = GD::Graph::Data->new([ 
    [@names], 
    [@scores], 
]) or die GD::Graph::Data->error; 

my $my_graph = GD::Graph::bars->new(); 
$my_graph->set(
    x_label   => 'Name', 
    y_label   => 'Score', 
    title   => 'A Simple Bar Chart', 
) or warn $my_graph->error; 
$my_graph->plot($data) or die $my_graph->error(); 
save_chart($my_graph, 'graph'); 

sub save_chart { 
    my $chart = shift or die "Need a chart!"; 
    my $name = shift or die "Need a name!"; 
    local(*OUT); 

    my $ext = $chart->export_format; 

    open(OUT, ">$name.$ext") or 
     die "Cannot open $name.$ext for write: $!"; 
    binmode OUT; 
    print OUT $chart->gd->$ext(); 
    close OUT; 
}