Go でグラフを plot するパッケージを試した

  • 22
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

はじめに

golangでグラフ描く.
詳しくはここ https://code.google.com/p/plotinum/wiki/Examples

インストール

% go get code.google.com/p/plotinum/                                                                                                                                             

これだけでは動かない.最初に動かそうとするとエラーが出るので,足りないと言われているpackageをインストールする.

% go run plotinum_sample.go                                                                                                                                                      
../lib/go/src/code.google.com/p/plotinum/vg/vgpdf/vgpdf.go:10:2: cannot find package "bitbucket.org/zombiezen/gopdf/pdf" in any of:
    /opt/local/go/src/pkg/bitbucket.org/zombiezen/gopdf/pdf (from $GOROOT)
    /Users/ikuo.kawaharada/lib/go/src/bitbucket.org/zombiezen/gopdf/pdf (from $GOPATH)
../lib/go/src/code.google.com/p/plotinum/vg/vgimg/vgimg.go:12:2: cannot find package "code.google.com/p/draw2d/draw2d" in any of:
    /opt/local/go/src/pkg/code.google.com/p/draw2d/draw2d (from $GOROOT)
    /Users/ikuo.kawaharada/lib/go/src/code.google.com/p/draw2d/draw2d (from $GOPATH)
../lib/go/src/code.google.com/p/plotinum/vg/font.go:21:2: cannot find package "code.google.com/p/freetype-go/freetype" in any of:
    /opt/local/go/src/pkg/code.google.com/p/freetype-go/freetype (from $GOROOT)
    /Users/ikuo.kawaharada/lib/go/src/code.google.com/p/freetype-go/freetype (from $GOPATH)
../lib/go/src/code.google.com/p/plotinum/vg/font.go:22:2: cannot find package "code.google.com/p/freetype-go/freetype/truetype" in any of:
    /opt/local/go/src/pkg/code.google.com/p/freetype-go/freetype/truetype (from $GOROOT)
    /Users/ikuo.kawaharada/lib/go/src/code.google.com/p/freetype-go/freetype/truetype (from $GOPATH)
../lib/go/src/code.google.com/p/plotinum/vg/vgimg/vgimg.go:13:2: cannot find package "code.google.com/p/go.image/tiff" in any of:
    /opt/local/go/src/pkg/code.google.com/p/go.image/tiff (from $GOROOT)
    /Users/ikuo.kawaharada/lib/go/src/code.google.com/p/go.image/tiff (from $GOPATH)
../lib/go/src/code.google.com/p/plotinum/vg/vgsvg/vgsvg.go:14:2: cannot find package "github.com/ajstarks/svgo" in any of:
    /opt/local/go/src/pkg/github.com/ajstarks/svgo (from $GOROOT)
    /Users/ikuo.kawaharada/lib/go/src/github.com/ajstarks/svgo (from $GOPATH)
% go get bitbucket.org/zombiezen/gopdf/pdf
% go get code.google.com/p/draw2d/draw2d
% go get code.google.com/p/freetype-go/freetype
% go get code.google.com/p/freetype-go/freetype/truetype
% go get code.google.com/p/go.image/tiff
% go get github.com/ajstarks/svgo

パッケージをインストールするときに

package code.google.com/p/plotinum/plot: exec: "hg": executable file not found in $PATH

とエラーが出たらmercurialをインストールすること.

折れ線グラフ

package main

import (
    "code.google.com/p/plotinum/plot"
    "code.google.com/p/plotinum/plotter"
    "code.google.com/p/plotinum/plotutil"
)

func main() {
        p, _ := plot.New()
        p.Title.Text = "Plot example"
        p.X.Label.Text = "X" // 日本語は通らなかった
        p.Y.Label.Text = "Y"
        plotutil.AddLinePoints(p, "", plotter.XYs{{0, 0}, {2,4}, {4,16}, {8, 64}})
        width := 4.0   // インチです!
        height := 4.0
        p.Save(width, height, "line_sample.png")
}

line_sample.png

ちなみにplotter.XYsの定義 (plotter/ plotter.go)は単純に2項組の列.

// XYs implements the XYer interface.
type XYs []struct{ X, Y float64 }

関数

color.RGBAのAはアルファチャンネルのA.透過度を表すらしい.

package main

import (
        "code.google.com/p/plotinum/plot"
        "code.google.com/p/plotinum/plotter"
        "code.google.com/p/plotinum/vg"
        "image/color"
        "math"
)

func main() {
        p, err := plot.New()
        if err != nil {
                panic(err)
        }
        p.Title.Text = "Functions"
        p.X.Label.Text = "X"
        p.Y.Label.Text = "Y"

        // A quadratic function x^2
        quad := plotter.NewFunction(func(x float64) float64 { return x * x })
        quad.Color = color.RGBA{B: 255, A: 255}

        // An exponential function 2^x
        exp := plotter.NewFunction(func(x float64) float64 { return math.Pow(2, x) })
        exp.Dashes = []vg.Length{vg.Points(2), vg.Points(2)}
        exp.Width = vg.Points(1)
        exp.Color = color.RGBA{G: 255, A: 255}

        // The sine function, shifted and scaled
        // to be nicely visible on the plot.
        sin := plotter.NewFunction(func(x float64) float64 { return 10*math.Sin(x) + 50 })
        sin.Dashes = []vg.Length{vg.Points(4), vg.Points(5)}
        sin.Width = vg.Points(4)
        sin.Color = color.RGBA{R: 255, A: 255}

        // Add the functions and their legend entries.
        p.Add(quad, exp, sin)
        p.Legend.Add("x^2", quad)
        p.Legend.Add("2^x", exp)
        p.Legend.Add("10*sin(x)+50", sin)
        p.Legend.ThumbnailWidth = vg.Inches(0.5)

        // Set the axis ranges.  Unlike other data sets,
        // functions don't set the axis ranges automatically
        // since functions don't necessarily have a
        // finite range of x and y values.
        p.X.Min = -20
        p.X.Max = 20
        p.Y.Min = 0
        p.Y.Max = 100

        // Save the plot to a PNG file.
        if err := p.Save(10, 10, "functions.png"); err != nil {
                panic(err)
        }
}

functions.png

点を打つ

もっと簡単な方法がありそうなんだけど,よくわからなかったので,Bubble Plotsを用いて点を打つ.
plotter.XYZsは3次元のベクトルで,zの値で点の大きさの比率を調整してくれる.今は点の大きさは一定でいいので同じ値にしている.
plotter.NewBubbles(plotter.XYZs{{0, 0, 1}, {1, 1, 1}, {2, 4, 1}, {3, 9, 1}, {4, 16, 1}}, vg.Points(2), vg.Points(2))
vg.Points(float64)はインチをピクセルに変換するだけ.第2引数で,点の最小値,第3引数で点の最大値を表している.Bubble Plotsのときはこの辺を調整する.

package main

import (
        "code.google.com/p/plotinum/plot"
        "code.google.com/p/plotinum/plotter"
        "code.google.com/p/plotinum/vg"
        "image/color"
)

func main() {
        p, err := plot.New()
        if err != nil {
                panic(err)
        }
        p.Title.Text = "Dots"
        p.X.Label.Text = "X"
        p.Y.Label.Text = "Y"

        bs, err := plotter.NewBubbles(plotter.XYZs{{0, 0, 1}, {1, 1, 1}, {2, 4, 1}, {3, 9, 1}, {4, 16, 1}}, vg.Points(2), vg.Points(2))
        if err != nil {
                panic(err)
        }
        bs.Color = color.RGBA{R: 196, B: 128, A: 255}
        p.Add(bs)

        if err := p.Save(4, 4, "bubble.png"); err != nil {
                panic(err)
        }
}

bubble.png