Chart :: Clicker中的直方图

时间:2016-08-24 14:31:23

标签: perl charts

我刚开始使用Chart::Clicker并且无法创建直方图。使用以下代码:

#!/usr/bin/perl -w

use strict;

use Gtk3 -init;
use Chart::Clicker;
use Chart::Clicker::Renderer::Bar;

my $data = {
        Alpha   => 3,
        Bravo   => 1,
        Charlie => 4,
        Delta   => 1,
        Echo    => 5,
};
my $counter = 0;

my $chart = Chart::Clicker->new;
my $context = $chart->get_context('default');
$context->range_axis->range(Chart::Clicker::Data::Range->new(lower => 0));
for my $value (sort keys %$data) {
        $chart->add_data($value, {$counter++ => $data->{$value}});
}
my $xaxis = Chart::Clicker::Axis->new(orientation => 'horizontal', position => 'bottom');
$xaxis->{tick_values} = [0 .. $counter-1];
$xaxis->{tick_labels} = [sort keys %$data];
$context->{domain_axis} = $xaxis;
$chart->set_renderer(Chart::Clicker::Renderer::Bar->new);
$chart->legend->visible(0);
$chart->draw;

my $win = Gtk3::Window->new;
my $img = Gtk3::Image->new_from_surface($chart->driver->surface);
$win->add($img);
$win->signal_connect('delete-event' => sub{Gtk3::main_quit} );
$win->show_all;
Gtk3::main;

产生以下输出:

Undesirable result

我想要的是更像这样的东西(图形编辑):

Desired result

我不关心x轴标签上的颜色。虽然我更喜欢这些酒吧按照我指定的顺序排列,但我并不关心订单。

修改

尝试@Borodin的建议会产生以下结果:

enter image description here

它更好,但不是很正确。现在有25个数据点,但是20个为零,因此它们没有显示,但它们仍占用X轴上的空间。两个在左侧被切断,两个在右侧被切断(缺失的那个在这个图表中恰好是零,所以它没有在其他地方那么糟糕。)

我尝试在每个方向上将X轴延伸一个刻度,这样就不会切断任何东西,但这会导致数据值重叠。我将零值更改为非零以说明发生了什么:

enter image description here

2 个答案:

答案 0 :(得分:1)

我通过切换到单个系列来实现它,但这是以色彩为代价的......好吧,不能拥有一切。

修正了其他一些问题:

  • 调整X轴刻度,使最左侧和最右侧的条不会被切断。
  • 强制Y轴刻度为整数(因为它计算出现次数,数据将始终为整数)。
  • 为Gtk3添加了解决方法< 3.10。

新代码:

#!/usr/bin/perl -w

use strict;
use Gtk3 -init;
use Chart::Clicker;
use Chart::Clicker::Renderer::Bar;
use POSIX qw/ceil/;

my $data = {
    Alpha   => 3,
    Bravo   => 1,
    Charlie => 4,
    Delta   => 1,
    Echo    => 5,
    Foxtrot => 9,
};

my $points = keys %$data;
my $counter = 0;
my $max = 0;
my $chart = Chart::Clicker->new;
for my $series (sort keys %$data) {
    $chart->add_data('histogram', {++$counter => $data->{$series}});
    $max = $data->{$series} if $data->{$series} > $max;
}
my $context = $chart->get_context('default');
my $yaxis = $context->range_axis;
$yaxis->range(Chart::Clicker::Data::Range->new(lower => 0));

# Force Y-axis ticks to integers
$yaxis->clear_tick_values;
my $increment = ceil($max / 10);
for(my $tick = 0; $tick <= $max; $tick += $increment) {
    $yaxis->add_to_tick_values($tick);
}
$yaxis->format('%d');

# Fix cropped bars on the left and right end of the X-axis
my $xaxis = $context->domain_axis;
$xaxis->tick_values([1 .. $counter]);
$xaxis->tick_labels([sort keys %$data]);
$xaxis->range(Chart::Clicker::Data::Range->new(lower => .5, upper => $counter+.5));
$context->domain_axis($xaxis);

$chart->set_renderer(Chart::Clicker::Renderer::Bar->new);
$chart->legend->visible(0);
$chart->draw;

my $win = Gtk3::Window->new;
my $loader = Gtk3::Gdk::PixbufLoader->new;
$chart->driver->surface->write_to_png_stream(sub {
    $loader->write([unpack 'C*', $_[1]]);
});
$loader->close;
my $img = Gtk3::Image->new_from_pixbuf($loader->get_pixbuf);
$win->add($img);
$win->signal_connect('delete-event' => sub{Gtk3::main_quit} );
$win->show_all;
Gtk3::main;

看起来像这样:

enter image description here

答案 1 :(得分:0)

阅读模块的文档,如果你想要不同颜色的条形,看起来你必须为每个数据集中的所有五个条形都包含一个值

也许是这样的事情?

my $i = 0;
for my $set (sort keys %$data) {
    my @values = (0) x keys %$data;
    $values[$i++] = $data->{$set};
    $chart->add_data($value, \@values);   
}