데이터 시각화: Perl(Chart::Clicker)을 사용하여 차트 만들기

여느 때와 마찬가지로 Perl에서 아름다운 도표를 만들 수 있는 여러 가지 방법이 있다.
  • Chart::Clicker
  • GD::Graph
  • Chart::Plotly

  • Chart::GGPlot - 실험
  • 이 문서에는 Chart::Clicker가 사용됩니다.
    하지만 그 전에 내가 먼저 알아볼게.지난 4년여 동안Chart:Clicker와 GD:Graph는 업데이트된 적이 없습니다.특히 GD::Graph의 경우 여러 가지 문제가 해결되지 않았으며 현재 상태를 알 수 없습니다.
    도표: 플로리는 내가 지금 더 흥미를 느끼는 물건이다.그것은 plotly.js에 기초를 두고 있다.
    나도 네가 계산하는 것을 격려한다Dash. 이것은 플로리 위에 세워진 것이다.js, React, Flask는 ML 및 데이터 과학 웹 응용 프로그램을 구축하는 데 사용됩니다.
    Perl 세계에서도 같은 저자(Chart:Plotly)에서 온 등가물Dash이 사용되며Mojolicious 또는Dancer2.그러나 현재 실험 단계에 있어 적극적으로 개발 중이다.나는 그것이 곧 생산에 투입되기를 바란다. 왜냐하면 나는 지체없이 한번 해 보고 싶기 때문이다.
    2-3년 전에 나는 Chart::Clicker를 사용한 적이 있는데, 그때는 내 요구에 아주 적합했다.그것은 Cairo에 기초를 두고 있다.내가 Chart::Plotly가 아니라 그것을 사용하는 이유는 매우 새것이기 때문이다.그러나 2021년에는 많은 아름다운 그래프 라이브러리(특히 앞부분)를 사용할 수 있다. 이것은 사용하기 쉬울 뿐만 아니라 보기에 좋은 눈이다.이 점을 주목하는 사람은 드물다-
  • Chart.js
  • D3.js
  • Amcharts
  • Highcharts
  • 아직 많지만, 이것은 오늘의 중점이 아니다.이런 것들로부터

  • 도표기본적이고 간단한 수요가 있을 때, js는 경량급과 우아하다.당신의 요구가 더욱 복잡하거나 지나치게 구체화되었을 때, 실현하기에는 아무런 어려움이 없으며, 당신은 그것을 실현하기 위해 추가 코드를 작성해야 한다.

  • D3.js는 길들이기 어려운 짐승이지만, 어떤 전투에서도 이길 수 있다.(나는 그것을 길들이는 데 시간이 좀 걸렸지만, 여전히 자신이 없다. 아마도 지금까지 나는 좋은 자바스크립트 개발자가 아니었을 것이다.)
  • 저는 개인적으로 Amcharts에 담보를 제공할 수 있습니다.Amcharts는 위의 두 라이브러리에 시간이 소요되는 경우에 적합합니다.그것은 네가 필요로 하는 모든 것이 있을 뿐만 아니라, 이미 만들어진 것이다.사이트에는 당신의 수요에 따라 고도로 설정할 수 있는 좋은 예가 많습니다. 특히 타자 스크립트로 작성된 사이트v4.
  • 이미 말했으니 우리의 예로부터 시작합시다.하나talk는 작가가 과거 어느 때 내놓은 것이다.너도 한번 보고 더 많은 정보를 얻을 수 있다.

    기본 차트 요소


    기본적인 도표 용어를 봅시다.부터canvasJS docs

    데이터 구성 만들기


    오늘 우리는 다중 접선도를 만들 것이다.사용하기 쉽고 고도로 설정할 수 있도록 입력 데이터 json 파일을 만들 것입니다
    {
        "title": "Number of automobiles sold per day by manufacturer",
        "domainAxis": {
            "data": ["2020-04-15", "2020-04-16", "2020-04-17", "2020-04-18"],
            "label": "Date"
        },
        "rangeAxis": {
            "lines": {
                "line1": {
                    "data": [10,3,5,9],
                    "legendName": "Honda"
                },
                "line2": {
                    "data": [20,15,8,10],
                    "legendName": "Toyota"
                },
                "line3": {
                    "data": [6,19,12,4],
                    "legendName": "Ford"
                },
                "line4": {
                    "data": [16,10,6,12],
                    "legendName": "Renault"
                }
            },
            "label": "Numbers of automobiles sold"
        }
    }
    
    이 이름들은 말하지 않아도 안다.domainAxis는 x축으로 날짜입니다.rangeAxis는 Y축으로 현재 3개의 선이 있다.

    디렉토리 구조


    우리의 디렉터리 구조는 매우 간단할 것이다.입력은 데이터를 입력하는 데 사용되고 출력은 도표를 만드는 데 사용되며 라이브러리는perl 모듈에 사용됩니다.
    ┣ 📂입력
    ┃ ┗ 📜데이터를 입력하다.json
    ┣ 📂해방당
    ┃ ┗ 📜차트를 생성합니다.오후.
    ┣ 📂출력
    ┣ 📜다선도.pl
    ┗ 📜자술하다.의학 박사

    모듈 만들기


    다중 접선도를 만드는 과정에서 나는 그것을 이해하는 데 많은 시간을 썼다.문서는 매우 좋지만, 나는 그것이 아직도 개선될 수 있다고 생각한다.왜 그랬는지, 그리고 이런 상황이 어떻게 발생했는지, 어떤 곳에서는 아직 답이 없다.좋은 일은 많은 사람들이 그 자리에 있었다는 것이다.그래서 너는 그것을 보고 너의 출로를 찾을 수 있다.
    그럼 우리 모듈을 만듭시다.
    package CreateCharts;
    use strict;
    use warnings;
    
    use Chart::Clicker;
    use Chart::Clicker::Context;
    use Chart::Clicker::Data::DataSet;
    use Chart::Clicker::Data::Marker;
    use Chart::Clicker::Data::Series;
    use Chart::Clicker::Axis::DateTime;
    
    use Geometry::Primitive::Rectangle;
    use Geometry::Primitive::Circle;
    
    use Graphics::Color::RGB;
    
    use DateTime;
    
    sub new {
        my ($class, @arguments) = @_;
        my $self = {@arguments};
        bless $self, $class;
        return $self;
    }
    
    sub _generate_specific_colors {
        my ($self) = @_;
    
        # build the color allocator
        # Add more colors in case your line is more than 6
        my $ca = Chart::Clicker::Drawing::ColorAllocator->new;
    
        my $red    = Graphics::Color::RGB->new({red => .75, green => 0,   blue => 0,   alpha => .8});
        my $green  = Graphics::Color::RGB->new({red => 0,   green => .75, blue => 0,   alpha => .8});
        my $blue   = Graphics::Color::RGB->new({red => 0,   green => 0,   blue => .75, alpha => .8});
        my $orange = Graphics::Color::RGB->new(red => .88, green => .48, blue => .09, alpha => .8);
        my $aqua   = Graphics::Color::RGB->new(red => 0, green => 1, blue => 1, alpha => .8);
        my $fuchsia = Graphics::Color::RGB->new(red => 1, green => 0, blue => 1, alpha => .8);
    
        $ca->add_to_colors($green);
        $ca->add_to_colors($red);
        $ca->add_to_colors($blue);
        $ca->add_to_colors($orange);
        $ca->add_to_colors($aqua);
        $ca->add_to_colors($fuchsia);
    
        return $ca;
    }
    
    sub _genrate_random_colors {
    
        # let Chart::Clicker autmatically pick complementing colors for you
        # https://metacpan.org/pod/Chart::Clicker::Drawing::ColorAllocator#AUTOMATIC-COLOR-ALLOCATION
        my $ca = Chart::Clicker::Drawing::ColorAllocator->new({
                seed_hue => 0,    #red
        });
        return $ca;
    }
    
    sub _add_series {
        my ($self, $x_axis, $y_axis) = @_;
        my $ds = Chart::Clicker::Data::DataSet->new;
        foreach my $axis (keys %{$y_axis}) {
            $ds->add_to_series(
                Chart::Clicker::Data::Series->new(
                    keys   => $x_axis,
                    values => $y_axis->{$axis}->{data},
                    name   => $y_axis->{$axis}->{legendName},
                )
            );
        }
        return $ds;
    }
    
    sub _add_title {
        my ($self, $cc, $title) = @_;
        $cc->title->font->family('Helvetica');
    
        $cc->title->text($title);
        $cc->title->font->size(20);
        $cc->title->padding->bottom(10);
    }
    
    sub _style_legend {
        my ($self, $cc) = @_;
        $cc->legend->font->size(20);
        $cc->legend->font->family('Helvetica');
    }
    
    sub _add_background {
        my ($self, $cc) = @_;
    
        # https://metacpan.org/pod/Graphics::Color::RGB
        my $titan_white = Graphics::Color::RGB->new(red => .98, green => .98, blue => 1, alpha => 1);
        my $white       = Graphics::Color::RGB->new(red => 1,   green => 1,   blue => 1, alpha => 1);
    
        $cc->plot->grid->visible(1);
        $cc->background_color($white);
        $cc->plot->grid->background_color($titan_white);
        $cc->border->width(0);
    }
    
    sub _add_label {
        my ($self, $def, $x_label, $y_label) = @_;
        $def->domain_axis->label($x_label);
        $def->range_axis->label($y_label);
        $def->domain_axis->label_font->size(20);
        $def->range_axis->label_font->size(20);
    }
    
    sub _add_shapes_to_lines {
        my ($self, $defctx) = @_;
    
        # https://metacpan.org/pod/Chart::Clicker::Renderer::Line#shape
        $defctx->renderer->shape(Geometry::Primitive::Circle->new({radius => 6,}));
    
        # https://metacpan.org/pod/Chart::Clicker::Renderer::Line#shape_brush
        $defctx->renderer->shape_brush(
            Graphics::Primitive::Brush->new(
                width => 2,
                color => Graphics::Color::RGB->new(red => 1, green => 1, blue => 1)
            )
        );
    
        $defctx->renderer->brush->width(2);
    }
    
    sub generate_chart {
        my ($self, $chart_loc, $summary_info) = @_;
    
        my $cc = Chart::Clicker->new(width => 800, height => 600, format => 'png');
    
        my $x_axis = $summary_info->{domainAxis};
        my $y_axis = $summary_info->{rangeAxis};
    
        my (@epoch_datetime);
    
        for my $datetime (@{$x_axis->{data}}) {
    
            # https://github.com/gphat/chart-clicker/blob/master/example/date-axis.pl
            # Need to convert date time string to epoch time
            my ($y, $m, $d) = split(/-/, $datetime);
            my $epoch = DateTime->new(year => $y, month => $m, day => $d)->epoch;
            push @epoch_datetime, $epoch;
        }
    
        my $ds = $self->_add_series(\@epoch_datetime, $y_axis->{lines});
        $cc->add_to_datasets($ds);
    
        # To generate random colors and let Chart::Clicker autmatically pick color
        # my $ca = $self->_genrate_random_colors();
    
        # To generate some specific colors for lines ise this function
        my $ca = $self->_generate_specific_colors();
        $cc->color_allocator($ca);
    
        $self->_add_title($cc, $summary_info->{title});
        $self->_style_legend($cc);
        $self->_add_background($cc);
    
        my $defctx = $cc->get_context('default');
    
        # For range axis
        $defctx->range_axis->range(Chart::Clicker::Data::Range->new(lower => 0));
        $defctx->range_axis->format('%d');
    
        # https://metacpan.org/pod/Chart::Clicker::Axis#fudge_amount
        # $defctx->range_axis->fudge_amount(0.02);
    
        # For domain axis
        $defctx->domain_axis(
            Chart::Clicker::Axis::DateTime->new(
                format => "%Y-%m-%d",
                ticks  => scalar @{$x_axis->{data}},
                position         => 'bottom',
                tick_label_angle => 0.78539816,                       # 45 deg in radians
                orientation      => 'vertical',
                tick_font        => Graphics::Primitive::Font->new({family => 'Helvetica', slant => 'normal'})
            )
        );
    
        $self->_add_label($defctx, $x_axis->{label}, $y_axis->{label});
        $self->_add_shapes_to_lines($defctx);
    
        $cc->write_output($chart_loc);
    }
    
    1;
    
    나는 하위 프로그램에 전용 이름을 사용하려고 시도했기 때문에 이해하기 쉽다.댓글도 달았다.
  • _generate_specific_colors - 선의 특정 색상 세트를 생성합니다.너는 자신의 필요에 따라 업데이트를 진행할 수 있다.
  • _generate_random_colors - 모듈에서 색상을 임의로 선택할 수 있습니다.
  • _add_series - 그래프에 시리즈/선을 추가합니다.내부 순환은 각 줄(총 3줄)에 대해 실행되고 데이터 집합에 추가됩니다.
  • _add_title - json 파일에 제공된 도표를 입력하기 위해 제목을 추가합니다.서로 다른 형식 옵션을 선택할 수 있으며, 사용자의 요구에 따라 업데이트할 수 있습니다.
  • _style_legend - 범례의 형식을 설정합니다.
  • _add_background - 차트에 배경색과 형식을 추가합니다.
  • _add_label - 차트를 다운로드하고 포맷합니다.
  • _add_shapes_to_lines - 선에 원형 및 브러시를 추가합니다.
  • generate_chart - 이것은 json 데이터를 입력해서 외부에서 호출하는 서브루틴입니다.
  • 서브루틴 이름 앞에 있는 밑줄을 알 수 있습니다.이것은 이 모듈의 전용 부분이기 때문이다.

    예. 모듈 사용


    이 모듈에 접근해서 도표를 만들기 위해 시작 스크립트를 만듭니다.
    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    use Cwd qw( abs_path );
    use File::Basename qw( dirname );
    use JSON;
    
    BEGIN {
        $ENV{"SCRIPT_DIR"} = dirname(abs_path($0));
    }
    
    use lib $ENV{"SCRIPT_DIR"} . "/lib";
    use CreateCharts;
    
    my $chart_out_file = $ENV{"SCRIPT_DIR"} . "/output/lineChart.png";
    
    sub read_json_file {
        my ($json_file) = @_;
        print "\nReading $json_file";
    
        open(my $in, '<', $json_file) or print "Unable to open file $json_file : $!";
        my $json_text = do { local $/ = undef; <$in>; };
        close($in) or print "\nUnable to close file : $!";
    
        my $config_data = decode_json($json_text);
        return $config_data;
    }
    
    sub main {
        my $data_in_json = read_json_file($ENV{"SCRIPT_DIR"} . "/input/input_data.json");
    
        my $chart = CreateCharts->new();
        $chart->generate_chart($chart_out_file, $data_in_json);
    }
    
    main;
    
    입력 파일에서 JSON 데이터를 읽고 호출하고 있습니다generate_chart.

    스크립트 실행


    이 스크립트를 실행하고 출력을 검사할 수 없습니다.

    위에서 본 출력은 linux 기계에서 나온 것이다.
    나는 이 모듈의 한 제한이 윈도우즈에서 실행하기 어렵다는 것을 발견했다.아마도 카이로나 다른 이유 때문일 것이다. 확실하지 않다.윈도우즈에 설치하는 것은 결코 간단하지 않다.나는 해 보았지만 성공하지 못했다.만약 당신이 방법을 알고 있다면 저에게 알려주세요.

    사용법


    내가 앞서 언급한 바와 같이, 새로운 현대 도서관이 사용되기 때문에, 너는 이 모듈을 사용하려고 시도하는 것은 거의 불가능하다.
    내가 오늘 그것의 가용성을 볼 수 있는 곳은--
  • 도표를 빨리 만들고 싶지만 웹에서 사용할 뜻은 없습니다.
  • 일정 시간 동안 도표를 만들고 이를 메일 첨부 파일로 보냅니다.입력한 내용은 SQL 또는 NoSQL 데이터베이스에서 가져올 수 있습니다.이것이 바로 내가 입력을 JSON으로 만든 이유이다. 이렇게 하면 쉽게 입력을 만들 수 있다.
  • 나는 단지 하나의 접선도의 예를 들었을 뿐이지만 그것도 많은 것을 지지한다 .자세한 내용은 other types를 참조하십시오.
  • 색깔이 도표에서 중요한 역할을 한다는 것을 기억해라.적당한 색깔과 적당한 불투명도(색조/포화도)를 선택하는 것이 중요하다.색깔의 선택에 따라 같은 도표는 좋은 것일 수도 있고 나쁜 것일 수도 있다.각종 온라인 도구가 너를 도울 수 있다.개인적으로 가장 좋아하는 것은 examples입니다.더 많은 정보를 얻을 수 있도록 색 튜토리얼을 보십시오.
  • 위의 예는 W3 color picker에서도 사용할 수 있습니다.

    github 다음


    나는 Chart::Plotly와 그 용법에 관한 글을 더 많이 쓸 것이다. 왜냐하면 나는 그것이 더욱 현대적이라는 것을 발견했기 때문이다.
    또한 Amcharts를 소개하고 Perl(Mojolicious)과 어떻게 결합해서 사용하고 반응하는지 소개할 것입니다.js
    표지 사진에서 추출

    좋은 웹페이지 즐겨찾기