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.



96
97
98
99
100
101
102
103
# File 'lib/redplot.rb', line 96

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



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/redplot.rb', line 81

def method_missing(*args)
#modification of "args" local var to auto-stringify fixnum
  (scoped_header = @header ) << args.map{ |arg|
    (arg.is_a? Numeric)? arg.to_s : arg           #specifically this line
  }.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]”



71
72
73
# File 'lib/redplot.rb', line 71

def command
  @command
end

#headerObject

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



71
72
73
# File 'lib/redplot.rb', line 71

def header
  @header
end

#pathObject

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



71
72
73
# File 'lib/redplot.rb', line 71

def path
  @path
end

#todrawObject (readonly)

holds callbacks to the data to be plotted



74
75
76
# File 'lib/redplot.rb', line 74

def todraw
  @todraw
end

Class Method Details

.release(instance) ⇒ Object

destructor to close the gnuplot process



77
78
79
# File 'lib/redplot.rb', line 77

def self.release instance
  instance.close
end

Instance Method Details

#<<(*args) ⇒ Object

directly write to the gnuplot process stdin



113
114
115
# File 'lib/redplot.rb', line 113

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


122
123
124
125
126
127
128
# File 'lib/redplot.rb', line 122

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



131
132
133
# File 'lib/redplot.rb', line 131

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


141
142
143
144
145
146
147
148
149
150
151
# File 'lib/redplot.rb', line 141

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



154
155
156
157
158
159
160
161
# File 'lib/redplot.rb', line 154

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



182
183
184
185
186
# File 'lib/redplot.rb', line 182

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



173
174
175
176
177
178
# File 'lib/redplot.rb', line 173

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



190
191
192
193
194
# File 'lib/redplot.rb', line 190

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



164
165
166
167
168
169
170
# File 'lib/redplot.rb', line 164

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



106
107
108
109
110
# File 'lib/redplot.rb', line 106

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