Class: RedPlot::Plotter

Inherits:
Object
  • Object
show all
Defined in:
lib/redplot.rb

Overview

main class whose instances are wrapper to gnuplot process the instances manage the necessary ressources and have all the callable methods

if an object is mixed with RedPlot, then an instance of Plotter is hooked to that object the instance of Plotter is then the path to gnuplot and helps to avoid name conflicts

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}, &configuration_block) ⇒ Plotter

Returns a new instance of Plotter.



82
83
84
85
86
87
88
89
# File 'lib/redplot.rb', line 82

def initialize(args={}, &configuration_block)
  @header   = args[:header]   ||  []
  @path     = args[:path]     ||  'redplot'
  @command  = args[:command]  ||  'plot'                
  @todraw   =                     ToDraw.new
  self.instance_eval &configuration_block if block_given?
  self
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/redplot.rb', line 70

def method_missing(*args)
  (scoped_header = @header ) << args.join(" ") + " "
  args[0].to_s.tap do |eval_space|        
    eval_space.singleton_class.instance_eval do 
      define_method(:method_missing) do |*args| 
        scoped_header[-1] << args.join(" ")  + " "
        self
      end
    end
  end
end

Instance Attribute Details

#commandObject

stores in an array settings such as “set xrange [a,b]”



60
61
62
# File 'lib/redplot.rb', line 60

def command
  @command
end

#headerObject

stores in an array settings such as “set xrange [a,b]”



60
61
62
# File 'lib/redplot.rb', line 60

def header
  @header
end

#pathObject

stores in an array settings such as “set xrange [a,b]”



60
61
62
# File 'lib/redplot.rb', line 60

def path
  @path
end

#todrawObject (readonly)

holds callbacks to the data to be plotted



63
64
65
# File 'lib/redplot.rb', line 63

def todraw
  @todraw
end

Class Method Details

.release(instance) ⇒ Object

destructor to close the gnuplot process



66
67
68
# File 'lib/redplot.rb', line 66

def self.release instance
  instance.close
end

Instance Method Details

#<<(*args) ⇒ Object

directly write to the gnuplot process stdin



99
100
101
# File 'lib/redplot.rb', line 99

def <<( *args )
  start.puts args
end

#drawObject

main client method to draw data happens in 3 steps:

1) sends the header args to gnuplot
2) sends the plot command
3) sends the data one block at a time


108
109
110
111
112
113
114
# File 'lib/redplot.rb', line 108

def draw
  start
  @proc.puts @header
  @proc.puts format_command( @command, @todraw.options )
  @todraw.callbacks.each { |block|  @proc.puts format_data( block.call ) }
  self
end

#format_command(command, options) ⇒ Object

format the plot command



117
118
119
# File 'lib/redplot.rb', line 117

def format_command( command, options )                 
  "%s '-' %s" %  [command, options.join(",'-' ")] #not tested yet
end

#format_data(raw_data) ⇒ Object

format the data from the callback blocks to fit gnuplot several interface are possible

1) a plain Array
2) an array of arrays, in which case these arrays are taken as data columns
3) anything with an each method 
   the block send to each takes one or more Numerics and/or numbers hidden in string


127
128
129
130
131
132
133
134
135
136
137
# File 'lib/redplot.rb', line 127

def format_data( raw_data )
  if raw_data.is_a? Array 
    if raw_data[0].is_a? Array  
      raw_data.transpose.map!{ |one_row| one_row.join " "}
    else
      raw_data
    end     
  else
   [].tap{ |data| raw_data.each { |*vals| data << vals.join(" ") } } #not tested yet
  end.<< 'end'
end

#save_data(path = @path) ⇒ Object

write to disc the result of format_Data



140
141
142
143
144
145
146
147
# File 'lib/redplot.rb', line 140

def save_data(path=@path)
  File.open( path+".dat", "w+") do |file|
    @todraw.callbacks.each do |block|  
      file.puts format_data( block.call ).tap{|ary| ary[-1] = ''}
    end
  end
  self
end

#save_eps(path = @path) ⇒ Object

set gnuplot terminal to eps and draw !the terminal will stay in eps mode



168
169
170
171
172
# File 'lib/redplot.rb', line 168

def save_eps(path=@path)
  start.puts  "set term postscript eps color blacktext \"Helvetica\" 24",  
              "set output '#{path}.eps'"
  draw
end

#save_graph(type = :png, path = @path) ⇒ Object

either draw in png or eps mode



159
160
161
162
163
164
# File 'lib/redplot.rb', line 159

def save_graph(type=:png, path=@path)
  case type
  when :png then save_png( path )
  when :eps then save_eps( path )
  end
end

#save_png(path = @path) ⇒ Object

set gnuplot terminal to png and draw !the terminal will stay in png mode



176
177
178
179
180
# File 'lib/redplot.rb', line 176

def save_png(path=@path)
  start.puts  'set term png enhanced',  
              "set output '#{path}.png'"
  draw
end

#save_script(path = @path) ⇒ Object

write to disc the content of @header and format_command



150
151
152
153
154
155
156
# File 'lib/redplot.rb', line 150

def save_script(path=@path)
  File.open( path + ".scr", "w+") do |file|
    file.puts @header
    file.puts format_command( @command, @todraw.options )
  end
  self
end

#startObject

start the gnuplot process if @proc is nil



92
93
94
95
96
# File 'lib/redplot.rb', line 92

def start
  @proc ||= IO.popen("gnuplot","w+").tap do |open|
    ObjectSpace.define_finalizer(self) { open.close }
  end
end