5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iRubyでPyPlotっぽくグラフを描けるようにしたい!

Last updated at Posted at 2017-02-22

はじめに

iRubyでデータ分析をすることが増えてきたので、グラフを描画できないことにより致命的に困っています。
これまでPython(jupyter)でデータ分析を行ってきたことから、PyPlotのようなライブラリがあればいいなと思ったので、同じことができるようにクラスを作ってみました。

PyPlotでは

以下のような方法でグラフが描画できます。

import matplotlib.pyplot as plt

plt.plot([4,6,5,7,8,1])
plt.show()

Unknown.png

なので、同じようにするならこんな感じでできないかなと...

require 'rbplot'

plt = RbPlot.new()
plt.plot([4,6,5,7,8,1])
plt.show()

RbPlotというクラスを作ってみる

先日、gnuplotを使えばiRubyの中でグラフを表示できるようになるということがわかったので、これを利用することにします。

必要最低限のものを作ってみると以下のとおり。

class RbPlot
  
  def initialize()
    @data = []
  end
    
  def plot(data)
    @data = data
  end

  def show()
    
    IRuby.display make(), mime: 'image/svg+xml'

  end
  
  def make()
    
    Gnuplot.open do |gp|
      
      Gnuplot::Plot.new( gp ) do |myplot|
        
        myplot.terminal "svg"
        
        myplot.data << Gnuplot::DataSet.new(@data) do |ds|
          ds.with = "lines"
          ds.notitle
        end
        
      end
      
    end
    
  end
  
end

使い方は以下のとおり。

plt = RbPlot.new
plt.plot([4,6,5,7,8,1])
plt.show()

スクリーンショット 2017-02-22 15.08.22.png

できた!

二本の線を描くには

PyPlotでは、以下のように記述すると描画できます。

import matplotlib.pyplot as plt

plt.plot([4,6,5,7,8,1])
plt.plot([2,4,3,6,5,9])
plt.show()

Unknown.png

...これは便利だ(-_-;)

では、同じようにできるよう先ほどのクラスを改造してみます。

class RbPlot2
  
  def initialize()
    @datas = []
  end
    
  def plot(data)
    @datas << data
  end

  def show()
    
    IRuby.display make(), mime: 'image/svg+xml'

  end
  
  def make()
    
    Gnuplot.open do |gp|
      
      Gnuplot::Plot.new( gp ) do |myplot|
        
        myplot.terminal "svg"
        
        @datas.each do |data|
          
          myplot.data << Gnuplot::DataSet.new(data) do |ds|
            ds.with = "lines"
            ds.notitle
          end
        
        end
          
      end
      
    end
    
  end
  
end

スクリーンショット 2017-02-22 15.19.51.png

できた!

グラフのタイトルを追加

PyPlotでタイトルを表示しようとすると以下のとおりです。

import matplotlib.pyplot as plt

plt.title("PyPlot")
plt.plot([4,6,5,7,8,1])
plt.plot([2,4,3,6,5,9])
plt.show()

Unknown.png

これもできるようにしてみます。

class RbPlot
  
  def initialize()
    @datas = []
    @title = ""
  end
    
  def title(title)
    @title = title
  end
  
  def plot(data)
    @datas << data
  end

  def show()
    IRuby.display make(), mime: 'image/svg+xml'
  end
  
  def make()
    Gnuplot.open do |gp|
      Gnuplot::Plot.new( gp ) do |myplot|
        myplot.terminal "svg"
        myplot.title @title
        @datas.each do |data|
          myplot.data << Gnuplot::DataSet.new(data) do |ds|
            ds.with = "lines"
            ds.notitle
          end
        end
      end
    end
  end
  
end

スクリーンショット 2017-02-22 15.26.16.png

できた!

最終的に...

その後もごにょごにょいじっていたら、それなりにできた!

require 'gnuplot'

class RbPlot
  
  def initialize()
    
    @arbitrary_lines = []
    @arbitrary_lines << "set terminal svg"
    
    @datas = []
    
  end
  
  def title(title)
    @arbitrary_lines << "set title '#{title}'"
  end
  
  def xlabel(xlabel)
    @arbitrary_lines << "set xlabel '#{xlabel}'"
  end

  def ylabel(ylabel)
    @arbitrary_lines << "set ylabel '#{ylabel}'"
  end
  
  def xlim(min, max)
    @arbitrary_lines << "set xrange [#{min}:#{max}]"
  end
  
  def ylim(min, max)
    @arbitrary_lines << "set yrange [#{min}:#{max}]"
  end
  
  def arbitrary_lines(value)
    @arbitrary_lines << "set " + value
  end
  
  def plot(value)
    @datas << {
      "type" => "lines",
      "value" => value
    }
  end
  
  def scatter(value)
    @datas << {
      "type" => "circles",
      "value" => value
    }
  end
  
  def show()
    IRuby.display make(), mime: 'image/svg+xml'
  end
    
  def make()
  
    Gnuplot.open do |gp|
      Gnuplot::Plot.new( gp ) do |myplot|
        @arbitrary_lines.each do |value|
          myplot.arbitrary_lines << value
        end
        @datas.each do |data|
          @with = data["type"]
          myplot.data << Gnuplot::DataSet.new(data["value"]) do |ds|
            ds.with = @with
            ds.notitle
          end
        end
      end
    end
    
  end
  
end

plt = RbPlot.new

x = [ 1, 3, 9]
y = [10,-2,-5]

plt.title("RbPlotテスト")
plt.ylabel("Y")
plt.xlabel("エックス")

plt.xlim(0,10)
plt.ylim(-10,20)

plt.arbitrary_lines("grid")

plt.plot([4,6,5,7,8,1])
plt.plot([2,4,3,6,5,9])
plt.plot([x,y])
plt.plot("x * x / 10")
plt.plot("10 * sin(x / 5 * 3.14)")

plt.show()

スクリーンショット 2017-02-22 15.36.44.png

どう?(^-^)

これで、それなりにiRubyでグラフが使えるようになった気がします。

5
2
0

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
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?