2023-02-23に投稿

Ruby + Numo::Gnuplot(numo-gnuplot gem)で散布図を描く

@obelisk68 さんに教えてもらったサンプル(ruby_gnuplot の記事のコメント, ブログ)で十分という気もしたのですが、一応自分でも触ってみました。

https://rubygems.org/gems/numo-gnuplot

https://github.com/ruby-numo/numo-gnuplot

準備

  • gnuplot コマンドをインストール
    • Ubuntu 18.04 の場合は sudo apt install gnuplot
  • Numo::Gnuplot をインストール
    • gem install numo-gnuplot

これだけ。

Numo::NArray は必須ではありません(インストールも不要)。以下は Numo::NArray なしで試しています。

最低限の例

PNG ファイルに出力する最低限の例です。

# sample.rb

require "numo/gnuplot"

xs = [1, 2, 3, 4, 5]
ys = [11, 22, 33, 44, 55]

Numo.gnuplot do
  set terminal: "png"
  set output: "output.png"
  plot xs, ys
end
  # 実行 ... output.png が生成される
ruby sample.rb

image

簡単ですね。
ちょっと見えにくいですが、 両端の点は枠線に重なっています。

環境

Ubuntu Linux 18.04
gnuplot -V #=> gnuplot 5.2 patchlevel 2
ruby -v    #=> ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
gem:
  numo-gnuplot 0.2.4

メモ

  • ruby_gnuplot と同様、インストールが楽なのが良い。gnuplot コマンドのインストールさえ済んでしまえば、他にインストール絡みでトラブルが起きる余地がなさそう。気分的に楽。
  • numo/gnuplot.rb ( https://github.com/ruby-numo/numo-gnuplot/blob/master/lib/numo/gnuplot.rb ) はコメントを除くと1,000行ちょいなので、サッと読める。ruby_gnuplot よりは大きめですが。
    • Numo::Gnuplot#initializeIO.popen したプロセスにコマンドを送る方式

ruby_gnuplot との機能比較でいえば、以下のあたりが違うようです:

  • Numo::NArray に対応している
  • IRuby に対応している
  • irb で対話的に操作できる
    • gnuplot の対話型インターフェイスの代わりに使えるっぽい

自分が使いそうな機能についてメモ

  • グラフのタイトル指定
  • 複数の系列の描画
  • 数式のプロット

などは READMEIntroduction.ja · ruby-numo/numo-gnuplot Wiki にサンプルがあるので、そっちを見てください。

軸タイトル

Numo.gnuplot do
  set xlabel: "x軸のラベル"
  set ylabel: "y軸のラベル"
  # ...

x軸, y軸の範囲指定

Numo.gnuplot do
  set xrange: 0..6
  set yrange: 0..60
  # ...

凡例の系列名

Numo.gnuplot do
  plot xs, ys, title: "series name"
  # ...

image

日本語フォント

無指定だと日本語が豆腐になりました。

Numo.gnuplot do
  set terminal: "png font 'VL Gothic,20'"
  # ...

image

点の代わりにラベルを表示する

xs = [1, 2, 3, 4, 5]
ys = [11, 22, 33, 44, 55]
labels = ["A", "B", "C", "D", "E"]

Numo.gnuplot do
  # ...
  plot xs, ys, labels, with: "labels"
end

image

デバッグ出力

debug_on を使うと、 gnuplot に送信しているコマンドを標準出力に出力することができます。

xs = [1, 2, 3, 4, 5]
ys = [11, 22, 33, 44, 55]

Numo.gnuplot do
  debug_on
  set terminal: "png"
  set output: "output.png"
  plot xs, ys
end
$ ruby sample_debug.rb
<set terminal png
<set output "output.png"
<plot '-' 
<1 11
<2 22
<3 33
<4 44
<5 55
<e

行頭の < を取り除いてやれば、そのまま gnuplot に渡せるようです。

$ ruby sample_debug.rb | sed -e 's/^<//g' > sample.gs

$ cat sample.gs
set terminal png
set output "output.png"
plot '-' 
1 11
2 22
3 33
4 44
5 55
e

  # スクリプトを gnuplot コマンドに渡して実行
$ gnuplot sample.gs

まとめたもの

せっかくなのでいろいろ含めたものも貼ってみます。
@obelisk68 さんが書いてくださったのとほぼ同じ。

require "numo/gnuplot"

xs = [1.0, 1.8, 3.1]
ys1 = [11, 25, 32]
ys2 = [21, 35, 42]
ys3 = [31, 45, 52]

Numo.gnuplot do
  set terminal: "png font 'Noto Sans CJK JP,12'"
  set output: "output.png"
  set title: "グラフのタイトル"
  set xrange: 0..6
  set yrange: 0..60
  set xlabel: "x軸のラベル"
  set ylabel: "y軸のラベル"

  plot xs, ys1, { title: "系列1(点のみ)" },
       xs, ys2, { title: "系列2(線のみ)", with: :lines },
       xs, ys3, { title: "系列3(点と線)", with: :linespoints },
       "x * 10", { title: "y = x * 10" }
end

image

with: :lines のように指定するか、または数式を使えば任意の直線が描画できるので、回帰直線もこれでいけますね(フィッティングの話については割愛)。

参考

ruby-numo/numo-gnuplot-demo: Ruby/Numo::Gnuplot Demo

めちゃくちゃいっぱいある gnuplot 本家のサンプルを Numo::Gnuplot に書き直した版。README から辿れる情報ですが一応。

この記事を読んだ人は(ひょっとしたら)こちらも読んでいます

Ruby + ruby_gnuplot(gnuplot gem)で散布図を描く

ruby_gnuplot もシンプルで良いと思いますよ。


SVG::Graph(svg-graph gem)で散布図を描く

Galaaz を触ってみた(TruffleRuby + ggplot2 で散布図を描いてみた)

Originally published at qiita.com
ツイッターでシェア
みんなに共有、忘れないようにメモ

sonota486

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント