Как я могу построить график временных рядов с Perl? - PullRequest
10 голосов
/ 21 октября 2009

У меня есть некоторые данные из базы данных (SQLite), отображающие значение (целое число) на дату. Дата - это строка в следующем формате: YYYY-MM-DD hh:mm. Даты распределены неравномерно. Я хочу нарисовать линейный график с датами на X и значениями на Y. Какой самый простой способ сделать это с Perl?

Я пытался DBIx :: Chart , но не мог заставить его распознать мои даты. Я также попробовал GD :: Graph , но, как сказано в документации:

GD :: Graph не поддерживает числовой x Ось так, как должно. Данные для X оси должны находиться на одинаковом расстоянии

Ответы [ 8 ]

11 голосов
/ 21 октября 2009

Вы можете использовать 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.

8 голосов
/ 21 октября 2009

Вы можете управлять gnuplot , используя Chart :: Gnuplot .

В качестве альтернативы, если SVG является приемлемым выходным форматом, существует SVG :: TT :: Graph .

3 голосов
/ 25 февраля 2011

Это помогло мне:

my $ctx = $chart->get_context('default');
$ctx->domain_axis(
    Chart::Clicker::Axis::DateTime->new(
        position        => 'bottom',
        orientation     => 'horizontal',
        ticks           => 5 ,
        format          => "%Y-%m-%d"
    )
);
3 голосов
/ 21 октября 2009

Я попробовал DBIx :: Chart, но не смог распознать мои даты.

Вы пытались перевести свои даты в метки времени Unix и использовать их как даты X?

2 голосов
/ 21 октября 2009

Самый простой способ сделать это с Perl - использовать Perl для запуска процесса gnuplot Вы можете использовать set timefmt x "%Y-%m-%d", и он автоматически проанализирует данные в имеющемся формате. Gnuplot также поддерживает множество выходных форматов.

1 голос
/ 02 февраля 2013

Следующее не будет работать в SQLLite, поскольку рекурсивные запросы не поддерживаются, но оно будет работать в Oracle.

Вы можете создать непрерывный временной ряд для дБ Oracle с помощью такого подзапроса:

(SELECT   TRUNC (SYSDATE - x / 1440, 'MI') ts
             FROM   (SELECT       LEVEL x
                           FROM   DUAL
                     CONNECT BY   LEVEL <= 60))

Затем свяжите этот временной ряд с данными диаграммы, используя левое соединение, как это:

    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 будет блокироваться, если все значения точек данных равны нулю (т. Е. Не определено). Не могу вам помочь, извините.

1 голос
/ 22 октября 2009

Вам нужен график для генерации в реальном времени или для одноразового отчета? Если последнее, то вы можете использовать модули 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 . Это невероятный пакет, но его нелегко использовать.

1 голос
/ 21 октября 2009

Я бы порекомендовал нормализовать даты в целые числа. Путь грубой силы, конечно, будет использовать секунды эпохи, но это может показаться не слишком хорошим на графике, поэтому нормализуйте с помощью линейного преобразования в некоторый приличный диапазон (я могу предоставить подробности того, как, если вы хотите).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...