Perl6 の SVG::Plot でグラフを描こう

こんにちは:whale2:
[Perl 6 Advent Calendar 2016](http://qiita.com/advent-calendar/2016/perl6)の8日目です。
今日はPerl6でグラフを描いてみようと思います。

## Perl6 でグラフを描くのに用いるモジュール

Perl6 でグラフを描画するときは [SVG::Plot](https://github.com/moritz/svg-plot/blob/master/lib/SVG/Plot.pm) を使います。

```bash:ドキュメントの参照
$ p6doc SVG::Plot
```

p6doc や、あと`examples`ディレクトリ以下のファイルを見ればなんとなく使い方がわかります(ざっくり)

## sin 関数のグラフ

```pl:draw_sin.pl6
use v6;
use SVG;
use SVG::Plot;

# 0 から 6 まで 0.1 刻みで生成
my @x = 0.0, 0.1 ... 6.0 ;

# それぞれ sin(x) を計算
my @y = @x».sin ;

# グラフの描画
my $fh = open 'sin.svg', :w ;
$fh.say(
  SVG.serialize: SVG::Plot.new(
      :title( 'sin 関数のグラフ' ),
      :width( 400 ),
      :height( 300 ),
      :background( '#fffff0' ),
      :colors( '#4169e1' ),
      :label-font-size(10),
      :labels( @x ),
      :values( $@y ),
  ).plot(:lines)
) ;
$fh.close ;
```

このスクリプトを実行すると、以下のようなファイルが出力されます。

![sin.svg.png](https://qiita-image-store.s3.amazonaws.com/0/76589/13cb48ab-5583-2222-bced-98f7698bacb6.png)

余談ですが、Python で `numpy.arange(0, 6, 0.1)` と書くと、生成されるのは [0.0, 0.1, ..., 5.9] であり、 6.0 は含まれません。
Perl6 で同じような値を得るためには `0.0, 0.1 ...^ 6.0` と書きます。

## cos 関数のグラフも追加

```pl:draw_sin_cos.pl6
use v6;
use SVG;
use SVG::Plot;

# 0 から 6 まで 0.1 刻みで生成
my @x = 0.0, 0.1 ... 6.0 ;

# それぞれ sin(x) を計算
my @y1 = @x.map:{ .sin } ;

# それぞれ cos(x) を計算
my @y2 = map *.cos, @x ;

# グラフの描画
my $fh = open 'sin_cos.svg', :w ;
$fh.say(
  SVG.serialize: SVG::Plot.new(
      title => 'sin 関数と cos 関数のグラフ' ,
      width => 400 ,
      height => 300 ,
      background => 'rgba(0,255,0,0.1)' ,
      colors => ( 'rgba(0,0,255,0.5)', 'rgba(255,0,0,0.5)' ) ,
      label-font-size => 10 ,
      labels => ( @x ) ,
      values => ( [@y1], [@y2] ) ,
      legend-font-size => 10 ,
      legends => ( 'sin', 'cos' ) ,
  ).plot(:lines)
) ;
$fh.close ;
```

ところどころ書き方を変えてみてます。

![sin_cos.svg.png](https://qiita-image-store.s3.amazonaws.com/0/76589/f9c8d3c6-daa4-2ed3-5435-7230c74fb722.png)

## ステップ関数とシグモイド関数

```pl:draw_transfer.pl6
use v6;
use SVG;
use SVG::Plot;

sub step_function(Rat $i){
  return ($i > 0).Int ;
}

sub sigmoid(Rat $i){
  return 1 / ( 1 + exp(-$i) ) ;
}

my @x = -5.0, -4.9 ... 5.0 ;
my @y1 = @x».&step_function ;
my @y2 = @x».&sigmoid ;

# グラフの描画
my $fh = open 'step_sigmoid.svg', :w ;
$fh.say(
   SVG.serialize: SVG::Plot.new(
      title => 'ステップ関数とシグモイド関数' ,
      width => 400 ,
      height => 300 ,
      min-y-axis => -0.1,
      background => 'ghostwhite' ,
      colors => ( 'mediumseagreen', 'orangered' ) ,
      label-font-size => 10 ,
      labels => ( @x ) ,
      values => ( [@y1], [@y2] ) ,
      legend-font-size => 10 ,
      legends => ( 'Step function', 'Sigmoid function' ) ,
  ).plot(:lines)
) ;
$fh.close ;
```

![step_sigmoid.svg.png](https://qiita-image-store.s3.amazonaws.com/0/76589/c2400d47-33db-7bdf-88bb-68bdde792376.png)

## 得票率円グラフ

英語で言うとパイチャート

```pl:draw_sanrio.pl6
use v6;
use SVG;
use SVG::Plot::Pie;

my %counts =
    ポムポムプリン => 807_389,
    シナモロール => 730_207,
    マイメロディ => 632_662,
    ぐでたま => 545_268,
    ハローキティ => 519_113,
    リトルツインスターズ => 377_873,
    YOSHIKITTY => 307_105,
    シンガンクリムゾンズ => 225_169,
    KIRIMIちゃん => 171_846,
    クロミ => 153_806,
    ;

my @colors = (
    '#ff6666',
    '#ff9900',
    '#ffcc00',
    '#99cc00',
    '#66cc66',
    '#00cccc',
    '#3399ff',
    '#9966ff',
    '#cc66cc',
    '#ff6699',
) ;

my @c = %counts.sort: *.value ;
my @values = @c».value ;
my @labels = @c».key ;

my $svg = SVG::Plot::Pie.new(
    width   => 400,
    height  => 300,
    values  => [$(@values)],
    labels  => @labels,
    colors => @colors ,
    title   => 'SANRIOキャラクター大賞2016TOP10',
).plot(:pie) ;

my $fh = open 'sanrio.svg', :w ;
$fh.say( SVG.serialize($svg) ) ;
$fh.close ;
```

YOSHIKITTY の存在感がヤヴァい。

![sanrio.svg.png](https://qiita-image-store.s3.amazonaws.com/0/76589/88bdc15f-a35a-bb25-1ae1-7995c7de6b89.png)


## おわり

グラフ化されると値がわかりやすくていいですね。[^comment]
ここまでおつきあいいただきありがとうございました:whale2:

明日は @titsuki さんです:full_moon_with_face:
よろしくおねがいします:camel:

## 参考と注釈

* [SVG::Plot](https://github.com/moritz/svg-plot/blob/master/lib/SVG/Plot.pm)
* [A SVG plotting adventure](https://perlgeek.de/blog-en/perl-6/svg-adventure.html)
* [ゼロから作るDeep Learning](https://www.oreilly.co.jp/books/9784873117584/)
* [SANRIOキャラクター大賞2016](http://sanriocharacterranking.com/result)

[^comment]: 見た目ちょっと無骨ではありますが