LoginSignup
3

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-06-05

@obelisk68 さんに教えてもらったサンプル(ruby_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.png

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

環境

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 コマンドのインストールさえ済んでしまえば、他にインストール絡みでトラブルが起きる余地がなさそう。気分的に楽 :ok_hand:
  • 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.png

日本語フォント

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

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

image.png

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

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.png

デバッグ出力

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.png

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

参考

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

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

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3