generating time series graphs with perl

P

Po Boy

I'm trying to find a perl module that will help me make a certain kind of
graph. I believe it's called a time-series graph, but I'm not sure. It's a
graph of how two variables behave over time. You can see a couple examples
at:

http://www.trendmacro.com/a/goodman/keyIndicators/pvCharting.asp
and
http://www.thestreet.com/comment/openbook/1332231.html

I have tried using gnuplot and the GD package for these graphs, but have
been unable to get either one to generate reasonable looking graphs. I
believe it's because the data that I'm graphing is not strictly described
by any function since some X value can have multiple Y values (just at
different times).

Has anyone had success in graphing this kind of data? Can you recommend a
module or some documentation or pointers that may help me out?

Looking forward to any help you can give me!

-pb
 
A

A. Sinan Unur

I'm trying to find a perl module that will help me make a certain kind
of graph. I believe it's called a time-series graph, but I'm not sure.
....

I have tried using gnuplot and the GD package for these graphs, but
have been unable to get either one to generate reasonable looking
graphs.

You must not have read the documentation.
Has anyone had success in graphing this kind of data? Can you
recommend a module or some documentation or pointers that may help me
out?

Well, you seem to have dismissed the one I would recommend. Use
GD::Graph:

http://search.cpan.org/~mverb/GDGraph-1.43/
Looking forward to any help you can give me!

The following example can get you started. Please read the docs.

#! perl

use strict;
use warnings;

use GD::Graph::linespoints;

my @data = (
[ '1998', '1999', '2000', '2001', '2002', '2003', '2004', ],
[ 3, 5, 6, 3, 1, 2, 5, ],
[ 5, 1, 2, 2, 3, 2, 7, ],
);

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

$graph->set(
x_label => 'Years',
y_label => 'Two Variables',
title => 'Time Series of v1 and v2',
) or die $graph->error;

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

open my $png, '>', 'tsplot.png' or die $!;
binmode $png;
print $png $gd->png;

__END__
 
P

Po Boy

The following example can get you started. Please read the docs.

That example does help me; it's similar to one I've been playing with.
Thanks for your help.

Unfortunately, it does not generate a graph at all like what I'm looking
for. The graph that it generates looks a lot like:

http://tinypic.com/cqp

Which shows two lines. I would like a graph showing how the two variables
relate to each other over time. An example of this is at:

http://www.thestreet.com/comment/openbook/1332231.html

Notice how the relationship of both variables over time is related by one
connected set of line segments? They may cross each other, which is odd.
That's the part that I have been unable to make GD perform.

I have read the docuementation rather carefully several times and looked
at all of the examples in the "samples" directory. I don't see anything
that mentions a graph quite like what I'm looking for.

When I feed in an array of data like:

my @data = (
[ 3, 5, 6, 3, 1, 2, 5, ],
[ 5, 1, 2, 2, 3, 2, 7, ],
);


(which is just your data with the years removed)

in hopes of making 6 segments connecting those points, it seems to sort
the data on the first array reference and make a graph like:

http://tinypic.com/cqw

That's not what I'm looking for either.

Have I adequately described why the image that I'm looking for is not that
trivial? It's tough for me to describe. Please let me know if you can
think of a way to make GD display this kind of data, or if you have any
other suggestions.

Thanks for your help from a fellow Cornellian (alumnus)!

-pb
 
E

Eric Bohlman

Which shows two lines. I would like a graph showing how the two
variables relate to each other over time. An example of this is at:

http://www.thestreet.com/comment/openbook/1332231.html

Notice how the relationship of both variables over time is related by
one connected set of line segments? They may cross each other, which
is odd. That's the part that I have been unable to make GD perform.

That type of graph is basically an augmented scatterplot. It looks like
what you need to do is first do an ordinary scatterplot, then modify the
colors of the first and last points in time sequence, and then add line
segments between the points in sequence (for the benefit of those with poor
color vision, you might want to add arrowheads on the line segments).
 
M

Martien Verbruggen

Which shows two lines. I would like a graph showing how the two variables
relate to each other over time. An example of this is at:

http://www.thestreet.com/comment/openbook/1332231.html

That sort of graph isn't possible with GD::Graph. I don't know off
hand of another package for Perl that does support that sort of thing.

GD::Graph would need quite some changes to be able to do that, so I
doubt I'll be able to add this any time soon.
Notice how the relationship of both variables over time is related by one
connected set of line segments? They may cross each other, which is odd.
That's the part that I have been unable to make GD perform.

Note that GD and GD::Graph are not the same thing. GD is a low level
image drawing package. GD::Graph is a graphing package built on top of
GD and GD::Text.

Martien
 
P

Po Boy

That sort of graph isn't possible with GD::Graph. I don't know off
hand of another package for Perl that does support that sort of thing.

Yuk! well, thanks for your help. Maybe I'll see if I can get gnuplot or
octave or something to do it.

-snip-
Note that GD and GD::Graph are not the same thing. GD is a low level
image drawing package. GD::Graph is a graphing package built on top of
GD and GD::Text.

Martien

Oh yeah. I guess I was so concerned with describing my goofy little graphs
that I misspoke. Sorry.

Thanks for your help.

-pb
 
A

A. Sinan Unur

That example does help me; it's similar to one I've been playing with.
Thanks for your help.

Unfortunately, it does not generate a graph at all like what I'm
looking for. The graph that it generates looks a lot like:

http://tinypic.com/cqp

Which shows two lines. I would like a graph showing how the two
variables relate to each other over time. An example of this is at:

http://www.thestreet.com/comment/openbook/1332231.html

OK, I have to admit I did not check that url before my initial response.
I just took time-series to mean time-series.
Notice how the relationship of both variables over time is related by
one connected set of line segments? They may cross each other, which
is odd. That's the part that I have been unable to make GD perform.

Well, my feeling is that chart was created in Excel (scatter-plot) and
then the relevant points and line segments were individually colored.
I have read the docuementation rather carefully several times and
looked at all of the examples in the "samples" directory. I don't see
anything that mentions a graph quite like what I'm looking for.

Correct. GD::Graph does not handle scatter plots.
Thanks for your help from a fellow Cornellian (alumnus)!

Hey, you are welcome.

Now, I do not know how much help the following would be but if you are on
a Windows system with Excel installed, you can automate the process of
generating these graphs to a certain extent by using something along the
lines of the following:

#! perl

use strict;
use warnings;

use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';
Win32::OLE->Option(Warn => 3);

my $excel;

# use existing instance if Excel is already running
eval {
$excel = Win32::OLE->GetActiveObject('Excel.Application')
};

die Win32::OLE->LastError if $@;

unless (defined $excel) {
$excel = Win32::OLE->new('Excel.Application', sub { $_[0]->Quit; })
or die Win32::OLE->LastError;
}

my $book = $excel->Workbooks->Add or die Win32::OLE->LastError;
my $sheet = $book->Worksheets(1) or die Win32::OLE->LastError;

$sheet->Range('A1:A5')->{Value} = [ [ 1 ], [ 5 ], [ 3 ], [ 2 ], [ 4 ], ];
$sheet->Range('B1:B5')->{Value} = [ [ 2 ], [ 1 ], [ 3 ], [ 5 ], [ 4 ], ];

my $chart = $book->Charts->Add;
$chart->{ChartType} = xlXYScatterLines;

$chart->SeriesCollection->Item(1)->{Values} = $sheet->Range('B1:B5')->
{Value};
$chart->SeriesCollection->Item(1)->{XValues} = $sheet->Range('A1:A5')->
{Value};

$chart->SeriesCollection->Item(1)->Points(1)->{MarkerBackgroundColor} =
0x0000cc;
$chart->SeriesCollection->Item(1)->Points(1)->{MarkerForegroundColor} =
0x0000cc;

$chart->SeriesCollection->Item(1)->Points(5)->{MarkerBackgroundColor} =
0xcccc00;
$chart->SeriesCollection->Item(1)->Points(5)->{MarkerForegroundColor} =
0xcccc00;

__END__

It is not that good looking given the fact that I know next to nothing
about the topic.
 
P

Po Boy

OK, I have to admit I did not check that url before my initial response.
I just took time-series to mean time-series.

I figured that may have been a problem. I still don't know a good, general
name for these types of graphs. They're not really parametric, either,
though they sometimes look like them.
Now, I do not know how much help the following would be but if you are
on a Windows system with Excel installed, you can automate the process
of generating these graphs to a certain extent by using something along
the lines of the following:

Well, no, it doesn't really help me on this one, but I've needed to do
something like that in Excel before, and I just may use that code on
another thing I do somewhat often. Thanks for showing me that stuff.

It is not that good looking given the fact that I know next to nothing
about the topic.


Thanks again for your help. I think I can get gnuplot to do a lot of this,
but the Chart::Graph module that I could use to talk to it looks rather
old.

-pb
 
M

Martien Verbruggen

Yuk! well, thanks for your help. Maybe I'll see if I can get gnuplot or
octave or something to do it.

Note that the chart you use can also be seen as a two-dimensional
straight projection of a three-dimensional chart with the time on the
Z axis (which points straight away from the view plane).

If you get gnuplot to plot a three-dimensional chart, switch off
display of the time axis and labels, and rotate it appropriately, you
might just have what you're looking for.

Any other package that does three-d charts and that lets you do a
straight projection and switch off axes probably will do as well.

Regards,
Martien
 
A

Anno Siegel

Martien Verbruggen said:
Note that the chart you use can also be seen as a two-dimensional
straight projection of a three-dimensional chart with the time on the
Z axis (which points straight away from the view plane).

I'd describe that as a parametric plot of an arbitrary curve. The
Z values play the role of the curve parameter.
If you get gnuplot to plot a three-dimensional chart, switch off
display of the time axis and labels, and rotate it appropriately, you
might just have what you're looking for.

Any other package that does three-d charts and that lets you do a
straight projection and switch off axes probably will do as well.

Any package that allows you to draw lines from one point to another
could basically do it. Assuming we have move_to( $x, $y) and
draw_to( $x, $y) (a la postscript), and the data is given in two
hashes %x and %y whose keys are the times (the same set of times in
both hashes), this draws the plot:

my @times = sort keys %x; # assuming a sortable time format
move_to( $x{ $_}, $y{ $_}) for shift @times;
draw_to( $x[ $_], $y[ $_]) for @times;

Anno
 
C

ctcgag

Po Boy said:
I figured that may have been a problem. I still don't know a good,
general name for these types of graphs. They're not really parametric,
either, though they sometimes look like them.

Why aren't they parametric?

I make graphs kind of like that with GD. It's not too bad if you just want
function rather than form. If you want pretty axis with ticks and
perfectly places labels, it is very tedious.

If GD::Graph did scatter plots, it would be pretty easy to use get_hotspot
and then draw the lines yourself in GD, over the image created by
GD::Graph. In fact, if I had it to do over again, I might try this method
with my graphs. I'd just bin the x values of the scatterplot into evenly
spaced intervals, so it stops being a scatter plot.


Xho
 
A

Anno Siegel

Martien Verbruggen said:
On 30 Apr 2004 12:06:20 GMT,
I'd describe that as a parametric plot of an arbitrary curve. The
Z values play the role of the curve parameter.


Any package that allows you to draw lines from one point to another
could basically do it. Assuming we have move_to( $x, $y) and
draw_to( $x, $y) (a la postscript), and the data is given in two
[...]

But then you'd still have to do the work of scaling the thing, and
drawing the axes yourself :)

Basically, what you say above is true of almost any line chart.

It's even true of any vector graphics, if you will, but that wasn't my
point.

The OP seemed to be unclear about what type of graphics is needed
for this kind of plot. So I threw in the term "parametric plot",
and gave a definition in terms of line drawing. That doesn't come
across very well in my post.

Anno
 
P

Po Boy

I'm trying to find a perl module that will help me make a certain kind of
graph. I believe it's called a time-series graph, but I'm not sure. It's a
graph of how two variables behave over time. You can see a couple examples
at:

http://www.trendmacro.com/a/goodman/keyIndicators/pvCharting.asp
and
http://www.thestreet.com/comment/openbook/1332231.html

Thanks to all who helped me with this problem. I ended up using
Chart::Graph to drive gnuplot to do this. Since that module doesn't know
about some of the new gnuplot features, it's unable to natively do arrows.
I packed the "set arrow" statements into the extra_opts parameter to make
it make the arrows.

-pb
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top