LoginSignup
4
6

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-05-29

準備

  • gnuplot コマンドをインストール
    • Ubuntu 18.04 の場合は sudo apt install gnuplot
  • ruby_gnuplot をインストール
    • gem install gnuplot

これだけ。

ただし、 Ruby 3.1.0 で matrix が bundled gem になったようなので、3.1.0 以降の場合は gem install matrix も必要です。
参考: [Ruby] Bundled gemsはGemfileに指定して使おう

最低限の例

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

# sample.rb

require "gnuplot"

Gnuplot.open do |gp|
  Gnuplot::Plot.new(gp) do |plot|
    plot.terminal "png"
    plot.output "output.png"

    x = [1, 2, 3, 4, 5]
    y = [11, 22, 33, 44, 55]
    plot.data << Gnuplot::DataSet.new([x, y])
  end
end
  # 実行 ... output.png が生成される
ruby sample.rb

image.png

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

PNG 以外にも、 SVG や PDF として出力することもできます。

環境

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:
  gnuplot 2.6.2
  matrix 0.4.2

メモ

  • とにかくインストールが楽なのが良い。gnuplot コマンドのインストールさえ済んでしまえば、他にインストール絡みでトラブルが起きる余地がなさそう。気分的に楽 :ok_hand:
  • gnuplot でできることは大体何でもできるはず。たぶん。
  • gnuplot.rb ( https://github.com/rdp/ruby_gnuplot/blob/master/lib/gnuplot.rb ) はコメントを除くと300行くらいなので、サッと読める
    • gnuplot 用のスクリプトに変換して gnuplot コマンドに渡しているだけ
  • 「○○がやりたいけどどうすればいい?」となった場合は gnuplot 向けの情報を探す
    • gnuplot は枯れたプロダクトなので、情報はたくさんある
    • すでに gnuplot に習熟している人は楽そう
  • Charty のバックエンドとして使える?(まだ試していません)
    • (追記) 2022-05-29 現在では未対応でした

非常に薄いラッパーなので、素の gnuplot をそのまま使うのと実はそんなに大差なくて、そこを踏まえた上で使う分には便利。
「gnuplot の使い方を覚えたいわけではないんだけどなあ……」という人には向かないかもしれません。

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

  • グラフのタイトル指定
  • x軸, y軸の範囲指定、軸タイトル指定
  • 複数の系列の描画
  • 数式のプロット

などは README にサンプルがあるので、そっちを見てください。

系列名の凡例

DataSet.new にブロックを付けると、ブロックパラメータとして DataSet のインスタンスが渡されるので、それを使って指定できる。

plot.data << Gnuplot::DataSet.new([x, y]) { |ds|
  ds.title = "dataset"
}

image.png

日本語フォント

無指定だと日本語が豆腐になりました。
gnuplot フォント 日本語 set terminal のような検索ワードで調べると、 Plot#terminal で指定できることが分かります。

Gnuplot.open do |gp|
  Gnuplot::Plot.new(gp) do |plot|
    plot.terminal "png font 'VL Gothic,20'"
    plot.output "output.png"

    x = [1, 2, 3]
    y1 = [11, 25, 32]

    plot.data << Gnuplot::DataSet.new([x, y1]) { |ds|
      ds.title = "系列1"
    }
  end
end

image.png

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

Gnuplot.open do |gp|
  Gnuplot::Plot.new(gp) do |plot|
    plot.terminal "png"
    plot.output "output.png"

    x = [1, 2, 3]
    y = [11, 22, 33]
    label = ["A", "B", "C"]
    plot.data << Gnuplot::DataSet.new([x, y, label]) { |ds|
      ds.with = "labels"
    }
  end
end

image.png


点とラベルを両方表示するのは若干面倒そう。

生成されたスクリプトだけ欲しい

以下のように Gnuplot.open にモンキーパッチを当てると、グラフの描画は行わずに gnuplot 用に生成されたスクリプトの出力だけを行うことができます。

module Gnuplot
  def self.open(persist = true)
    io = $stdout
    yield io
  end
end

Gnuplot.open do |gp|
  Gnuplot::Plot.new(gp) do |plot|
    x = [1, 2, 3]
    y = [11, 22, 33]
    plot.data << Gnuplot::DataSet.new([x, y])
  end
end
$ ruby sample_print_script.rb > sample.gs

$ cat sample.gs
plot '-'
1 11
2 22
3 33
e

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

まとめたもの

せっかくなのでいろいろ含めたものも貼ってみます。

require "gnuplot"

Gnuplot.open do |gp|
  Gnuplot::Plot.new(gp) do |plot|
    plot.terminal "png font 'Noto Sans CJK JP,12'"
    plot.output "output.png"
    plot.title "グラフのタイトル"
    plot.xrange "[0:6]"
    plot.yrange "[0:60]"
    plot.xlabel "x軸のラベル"
    plot.ylabel "y軸のラベル"

    x = [1, 2, 3]
    y1 = [11, 25, 32]
    y2 = [21, 35, 42]
    y3 = [31, 45, 52]

    plot.data << Gnuplot::DataSet.new([x, y1]) { |ds|
      ds.title = "系列1"
    }

    plot.data << Gnuplot::DataSet.new([x, y2]) { |ds|
      ds.title = "系列2(線のみ)"
      ds.with = "lines"
    }

    plot.data << Gnuplot::DataSet.new([x, y3]) { |ds|
      ds.title = "系列3(点と線)"
      ds.with = "linespoints"
    }

    # 数式
    plot.data << Gnuplot::DataSet.new("x * 10") { |ds|
      ds.title = "y = x * 10"
    }
  end
end

image.png

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

参考


日本語のPDFがあります。


豊富なサンプル。gnuplot マジ何でもできるな、という気持ちになります。

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

4
6
2

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
4
6