はじめに
この記事は Go Advent Calendar 2021 の 14 日目の記事です。(執筆時点で 15 日になりそうなのは内緒)
今回は以前簡易的なグラフを作る際に良かった gonum.org/v1/plot
の紹介をしたいと思います。
背景
普段は Go を使ってバックエンドの開発を行っているのですが、たまにグラフをプロットするときがあります。
この辺のプロット周りのライブラリはどの言語にもあると思いますが、Go でも簡単にできないかなと思い探したところ、この plot に出会いました。
細かいグラフを出すのは結構たいへんですが、自分が思っているような簡単なグラフはすぐ生成できました。
gonum.org/v1/plot で作ったグラフ
まず最初にこの plot で作成したグラフを紹介します。
近似数値微分法 を使った 3・5・7・9 点近似数値微分の誤差
減衰振動
グラフの詳細は割愛しますが、手軽に良さげなグラフを描画することができます。
グラフ生成方法
自前で軽くラップしているのでわかりにくいかもしれないですが、以下のようになります。
plot.New()で初期化でき、その中に情報を格納していきます。
プロットするグラフの種類ですが、折れ線グラフや散布図、ヒストグラムなど普通に使う分には問題ないくらいには用意されています。
func main() {
plps := printPlot.NewPlotLinePoints()
plps.GeneralForPlot.Path = "image.png"
plps.Plot.X.Label.Text = "x"
plps.Plot.Y.Label.Text = "y"
plps.Pts = append(plps.Pts, solver(yFunc))
plps.PrintPlotLinePoints()
}
// printPlotパッケージ(ラップ)
type PlotLinePoints struct {
GeneralForPlot GeneralForPlot
Plot plot.Plot
Pts []plotter.XYs
}
// New LinePoints 新規作成
// v0.9.0 から plot.New() でエラーを返さなくなったので注意(このコード書いたのが結構前です。)
func NewPlotLinePoints() (*PlotLinePoints){
p, _ := plot.New()
pts := make([]plotter.XYs, 0)
plps := &PlotLinePoints{
GeneralForPlot: GeneralForPlot{
Path: "image.png",
},
Plot: *p,
Pts: pts,
}
return plps
}
// PrintPlotLinePoints 描画
func (ps *PlotLinePoints)PrintPlotLinePoints() {
ps.Plot.Add(plotter.NewGrid())
for key, _ := range ps.Pts {
graph,_, err := plotter.NewLinePoints(ps.Pts[key])
if err != nil {
panic(err)
}
graph.Color = randomColor()
ps.Plot.Add(graph)
ps.Plot.Legend.Add("line:"+strconv.Itoa(key), graph)
}
if err := ps.Plot.Save(6*vg.Inch, 6*vg.Inch, ps.GeneralForPlot.Path); err != nil {
panic(err)
}
}
どの方法で描画するのかなど毎回設定するのが面倒だったのでオレオレラッパーを作成し、実装しています。
使う場合は、main 関数で使っているように最低限の情報を入れてグラフの画像を生成するようにしています。
plps.Pts = append(plps.Pts, solver(yFunc))
というように描画したい点の集合を append することでいい感じに表示してくれます。
プロットは ps.Plot.Save(6*vg.Inch, 6*vg.Inch, ps.GeneralForPlot.Path)
で行っています。
最後に
簡単になりましたが以上になります。
グラフのプロットというと Python などを思い浮かべることが多いと思いますが、凝らなければ(というより大抵のグラフは) Go でも同じように描画できると思います。
最後までご覧いただきありがとうございました。