準備
- gnuplot コマンドをインストール
- Ubuntu 18.04 の場合は
sudo apt install gnuplot
- Ubuntu 18.04 の場合は
- 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
以上。簡単ですね。
ちょっと見えにくいですが、 両端の点は枠線に重なっています。
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 コマンドのインストールさえ済んでしまえば、他にインストール絡みでトラブルが起きる余地がなさそう。気分的に楽
- 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"
}
日本語フォント
無指定だと日本語が豆腐になりました。
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
点の代わりにラベルを表示する
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
点とラベルを両方表示するのは若干面倒そう。
生成されたスクリプトだけ欲しい
以下のように 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
ds.with = "lines"
を使うか、または数式を使えば任意の直線が描画できるので、回帰直線もこれでいけますね(フィッティングの話については割愛)。
参考
日本語のPDFがあります。
豊富なサンプル。gnuplot マジ何でもできるな、という気持ちになります。
この記事を読んだ人は(ひょっとしたら)こちらも読んでいます