Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

csv2png.pl - Line Graphs from a CSV file

by clemburg (Curate)
on Feb 16, 2001 at 23:14 UTC ( #58943=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info clemburg
Description: This is a small script that takes CSV data as input and generates a PNG file displaying a line graph as output. Basically, each column in the CSV file is a data series that will be displayed as a line graph. The first series labels the X axis.

#!/usr/bin/perl

use strict;

use Getopt::Std;
use GD::Graph::linespoints;
use Text::ParseWords;

# --------------------------------------------------
# setup
# --------------------------------------------------

my %opts = ();
getopts('d:c:k', \%opts);

my $config_file = ($opts{'c'} || "csv2png.conf");
my $delimiter   = ($opts{'d'} || ';');
my $keep        = ($opts{'k'} || 0);

my $input_file  = $ARGV[0];
my ($output_file) = ($input_file =~ /(.*)\./);

die usage() unless ($input_file && $output_file);

# sets globals %graph, %config and @legends
use vars qw(%graph %config @legends);

# can't use do() here because of PerlApp limitations :-(
{
    open(CF, "<$config_file") or die "Error: no open for $config_file:
+ $!";
    local $/ = undef;
    my $configuration = <CF>;
    eval "$configuration";
    close(CF);
}
    

# --------------------------------------------------
# action
# --------------------------------------------------

my @data =  read_data_from_csv($input_file);

my $my_graph = new GD::Graph::linespoints($graph{'width'}, $graph{'hei
+ght'});

$my_graph->set(%config); 
$my_graph->set_legend(@legends);

$my_graph->plot(\@data);
save_chart($my_graph, $output_file);

# --------------------------------------------------
# subs
# --------------------------------------------------

sub read_data_from_csv
{
    my ($fh) = @_;
    my @d = ();

    open(FH, "<$fh") || die "Error: no open for $fh: $!";
    while (<FH>) {
        chomp;
        my @row = parse_line($delimiter, $keep, $_);
        for (my $i = 0; $i <= $#row; $i++) {
            undef $row[$i] if ($row[$i] eq 'undef');
            push @{$d[$i]}, $row[$i];
        }
    }
    close (FH);
    return @d;
}

sub usage {
    print << "EOU";

Usage: $0 [-d][-k][-c] input-filename

$0: reads a CSV file and creates a PNG line graphic from it
Options:
    c: configuration file name (default "csv2png.conf")
    d: delimiter for CSV file (Perl regular expression, default ";")
    k: keep quotes around data (default off)

EOU
}

sub save_chart
{
    my ($chart, $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;
}

1;

Sample configuration file:

# must create the following variables:
# %config (graph options, see perldoc GD::Graph)
# @legends (graph methods, see perldoc GD::Graph)

%graph = (
    width => 600,
    height => 400,
);

%config = ( 
    width         => 600,
    height        => 400,
    x_label       => 'X-Axis',
    y_label       => 'Y-Axis',
    title         => 'Chart',
    y_min_value   => '0',
    y_max_value   => '5000',
    y_tick_number => '10',
    y_label_skip  => '2',

    transparent   => 0,
    bgclr         => 'white',
);

@legends = (
    'Page Views',
    'Visits',
);

Sample data:

27/04;678;443
28/04;1476;503
29/04;373;98
30/04;312;129
01/05;1136;331
02/05;1250;378
Replies are listed 'Best First'.
Re: csv2png.pl - Line Graphs from a CSV file
by a (Friar) on Feb 17, 2001 at 10:21 UTC
    You know, I have this data file of pages scanned per day and I was thinking it'd be nice to show the bosses a little line graph ... thanks.

    Update: Yup, just what the bosses wanted, works like a charm. GD::Graph is so easy! However getting GD::etc installed was a little messy as my libgd was older (and shared) and I didn't remove it first on upgrading. That then broke mrtg which was using the old shared lib ... <sigh> something about 'every solution brings w/ it a new set of problems' ... least the bosses are happy about the stats. And recompling rateup was relatively painless.

    a

Re: csv2png.pl - Line Graphs from a CSV file
by slojuggler (Beadle) on Mar 21, 2002 at 21:42 UTC
    I figured out the problem...my goof!

    I initially cut and pasted the code from the page. So, I ended up deleting the two red +s that dot the csv2png.pl code as a result of long lines going past the page limit.

    I'm posting this to help out other monks in the event they obtain the weird error that I got the first time.

    Neat program..thanks!

      By following the stated steps, I was able to create a gif file but unable to see any graph lines. The Windows Picture Viewer claimed "No preview available". Why is that so? What did I do wrong?

        Not sure. Works for me:

        Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:\strawberry\perl>perl -v This is perl, v5.10.0 built for MSWin32-x86-multi-thread Copyright 1987-2007, Larry Wall Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge.

        viz. csv2png.gif

        Note that the output is actually a .gif (not a .png); maybe try a different graphics viewer?

        HTH,

        planetscape
      can you share me edited code in below address. i followed your instruction and deleted entries but still getting syntax error. thanks. wannamyfan@gmail.com
      Hi, I'm new Perl user, i need help to generate graph for 3 axes. input(x-axis) output1(y-axis) output2(z-axis) The input file is .csv Kindly provide me the input. Thanks, sgupta
Re: csv2png.pl - Line Graphs from a CSV file
by wazoox (Prior) on Feb 23, 2009 at 18:01 UTC
    nice, but it creates gif files for me :)
Re: csv2png.pl - Line Graphs from a CSV file
by slojuggler (Beadle) on Mar 08, 2002 at 17:06 UTC
    Hi, when I try running this on Activestate Perl 5.6.1, build 631 using the input file as csvin.txt, I get the following:

    C:\scripts>csv2png.pl csvin.txt gd-png: fatal libpng error: No IDATs written into file gd-png error: setjmp returns error condition

    Any ideas?

Re: csv2png.pl - Line Graphs from a CSV file
by Anonymous Monk on Oct 01, 2017 at 02:52 UTC

    Friends

    I am still getting warning for syntax error on line 101. i am new in perl please suggest

    #!/usr/bin/perl use strict; use Getopt::Std; use GD::Graph::linespoints; use Text::ParseWords; # -------------------------------------------------- # setup # -------------------------------------------------- my %opts = (); getopts('d:c:k', \%opts); my $config_file = ($opts{'c'} || "csv2png.conf"); my $delimiter = ($opts{'d'} || ';'); my $keep = ($opts{'k'} || 0); my $input_file = $ARGV[0]; my ($output_file) = ($input_file =~ /(.*)\./); die usage() unless ($input_file && $output_file); # sets globals %graph, %config and @legends use vars qw(%graph %config @legends); # can't use do() here because of PerlApp limitations :-( { open(CF, "<$config_file") or die "Error: no open for $config_file: +$!"; local $/ = undef; my $configuration = <CF>; eval "$configuration"; close(CF); } # -------------------------------------------------- # action # -------------------------------------------------- my @data = read_data_from_csv($input_file); my $my_graph = new GD::Graph::linespoints($graph{'width'}, $graph{'hei +ght'}); $my_graph->set(%config); $my_graph->set_legend(@legends); $my_graph->plot(\@data); save_chart($my_graph, $output_file); # -------------------------------------------------- # subs # -------------------------------------------------- sub read_data_from_csv { my ($fh) = @_; my @d = (); open(FH, "<$fh") || die "Error: no open for $fh: $!"; while (<FH>) { chomp; my @row = parse_line($delimiter, $keep, $_); for (my $i = 0; $i <= $#row; $i++) { undef $row[$i] if ($row[$i] eq 'undef'); push @{$d[$i]}, $row[$i]; } } close (FH); return @d; } sub usage { print << "EOU"; Usage: $0 [-d][-k][-c] input-filename $0: reads a CSV file and creates a PNG line graphic from it Options: c: configuration file name (default "csv2png.conf") d: delimiter for CSV file (Perl regular expression, default ";") k: keep quotes around data (default off) EOU } sub save_chart { my ($chart, $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; } 1;

    Sample configuration file:

    # must create the following variables: # %config (graph options, see perldoc GD::Graph) # @legends (graph methods, see perldoc GD::Graph) %graph = ( width => 600, height => 400, ); %config = ( width => 600, height => 400, x_label => 'X-Axis', y_label => 'Y-Axis', title => 'Chart', y_min_value => '0', y_max_value => '5000', y_tick_number => '10', y_label_skip => '2', transparent => 0, bgclr => 'white', ); @legends = ( 'Page Views', 'Visits', );
Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://58943]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2019-08-18 04:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If you were the first to set foot on the Moon, what would be your epigram?






    Results (134 votes). Check out past polls.

    Notices?