我有一些来自数据库(SQLite)的数据,将值(整数)映射到日期。日期是具有以下格式的字符串:YYYY-MM-DD hh:mm
。日期不均匀分布。我想绘制一个包含X
日期和Y
上的值的折线图。使用Perl最简单的方法是什么?
我试过DBIx::Chart,但我无法识别我的约会。我也试过GD::Graph,但正如文档所说:
GD :: Graph不支持数字x 轴应该如何。 X的数据 轴应该等间隔
答案 0 :(得分:11)
您可以使用Chart :: Clicker的Axis :: DateTime:
#!/usr/local/bin/perl -w
use strict;
use Chart::Clicker;
use Chart::Clicker::Axis::DateTime;
use Chart::Clicker::Data::Series;
use Chart::Clicker::Data::DataSet;
use Chart::Clicker::Renderer::Point;
my $cc = Chart::Clicker->new;
my $series = Chart::Clicker::Data::Series->new(
values => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
keys => [
1256147117, 1256148117, 1256149117, 1256150117, 1256151117, 1256152117,
1256153117, 1256154117, 1256155117, 1256156117
],
);
my $ctx = $cc->get_context('default');
$ctx->domain_axis(Chart::Clicker::Axis::DateTime->new(position => 'bottom', orientation => 'horizontal'));
my $ds = Chart::Clicker::Data::DataSet->new(series => [ $series ]);
$cc->add_to_datasets($ds);
$cc->write_output('foo.png');
您必须将您的时间转换为Unix时间戳,但它是DWIM。
答案 1 :(得分:8)
您可以使用gnuplot开启Chart::Gnuplot。
或者,如果SVG是可接受的输出格式,则有SVG::TT::Graph。
答案 2 :(得分:3)
我尝试了DBIx :: Chart,但我无法识别我的日期。
您是否尝试将日期转换为Unix-Timestamps并将其用作X日期?
答案 3 :(得分:3)
这对我有用:
my $ctx = $chart->get_context('default');
$ctx->domain_axis(
Chart::Clicker::Axis::DateTime->new(
position => 'bottom',
orientation => 'horizontal',
ticks => 5 ,
format => "%Y-%m-%d"
)
);
答案 4 :(得分:2)
我发现使用Perl执行此操作的最简单方法是使用Perl运行gnuplot进程。您可以使用set timefmt x "%Y-%m-%d"
,它会自动以您拥有的格式解析数据。 Gnuplot还支持各种输出格式。
答案 5 :(得分:1)
我建议将日期标准化为整数。蛮力方式当然会使用纪元秒,但在图表上可能看起来不太好,所以通过线性变换归一化到一些不错的范围(我可以提供您希望的详细信息)。
答案 6 :(得分:1)
您是否需要实时生成图表,还是需要一次性报告?如果是后者,那么您可以使用DateTime模块生成Excel值并在Excel(或其开源对应物)中绘制它们。
use DateTime::Format::MySQL;
use DateTime::Format::Excel;
my $dt = DateTime::Format::MySQL->parse_datetime( '2003-01-16 23:12:01' );
print $dt, "\n";
my $daynum = DateTime::Format::Excel->format_datetime($dt);
print $daynum, "\n";
以前我用Asymptote做了类似的事情。这是一个令人难以置信的包,但它不容易使用。
答案 7 :(得分:1)
以下在SQLLite中不起作用,因为不支持递归查询,但它可以在Oracle中使用。
您可以使用以下子查询为Oracle dBs创建连续时间序列:
(SELECT TRUNC (SYSDATE - x / 1440, 'MI') ts
FROM (SELECT LEVEL x
FROM DUAL
CONNECT BY LEVEL <= 60))
然后使用LEFT JOIN将该时间序列链接到您的图表数据:
SELECT TO_CHAR (A.TS, 'DD/MM/YYYY HH24:MI') TS
, b.DATAPOINT1, b.DATAPOINT2
FROM (SELECT TRUNC (SYSDATE - x / 1440, 'MI') ts
FROM (SELECT LEVEL x
FROM DUAL
CONNECT BY LEVEL <= 60)) a
, MY_CHART_DATA b
WHERE a.ts = b.ts(+) ORDER BY a.TS;
上面的示例将绘制最后60分钟,并将与DBIx :: Chart一起工作**。要将分辨率更改为小时,请将“MI”更改为“HH24”,或者每24小时更改一次,您可以一起省略日期格式参数。
要更改范围,只需将CONNECT BY LEVEL值设置为您需要以指定分辨率绘制的时间序列点数。
**注意:如果所有数据点值都为零(即未定义),则DBIx :: Chart将为barf。对不起你,对不起。