gnuplotrb 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,7 @@ module GnuplotRB
5
5
  # this 'x*sin(x)' or filename) and options related to original dataset
6
6
  # in gnuplot (with, title, using etc).
7
7
  class Dataset
8
- include OptionHandling
8
+ include Plottable
9
9
  ##
10
10
  # Data represented by this dataset
11
11
  attr_reader :data
@@ -15,7 +15,7 @@ module GnuplotRB
15
15
  OPTION_ORDER = %w(index using axes title)
16
16
 
17
17
  ##
18
- # Hash of init handlers for data given in
18
+ # Hash of init handlers for data given in
19
19
  # different containers.
20
20
  INIT_HANDLERS = Hash.new(:init_default).merge(
21
21
  String => :init_string,
@@ -50,61 +50,8 @@ module GnuplotRB
50
50
  # The same data but datablock stores it in temp file:
51
51
  # Dataset.new(points, with: 'points', title: 'Points', file: true)
52
52
  def initialize(data, **options)
53
- self.send(INIT_HANDLERS[data.class], data, options)
54
- end
55
-
56
- ##
57
- # Method for inner use.
58
- def init_string(data, options)
59
- @type, @data= if File.exist?(data)
60
- [:datafile, "'#{data}'"]
61
- else
62
- [:math_function, data.clone]
63
- end
64
- @options = Hamster.hash(options)
65
- end
66
-
67
- ##
68
- # Method for inner use.
69
- def init_dblock(data, options)
70
- @type = :datablock
71
- @data = data.clone
72
- @options = Hamster.hash(options)
73
- end
74
-
75
- ##
76
- # Method for inner use.
77
- # TODO: make it better
78
- def init_daru_frame(data, options)
79
- options[:title] ||= data.name
80
- if options[:using]
81
- options[:using] = " #{options[:using]} "
82
- data.vectors.to_a.each_with_index do |daru_index, array_index|
83
- options[:using].gsub!(/([\:\( ])#{daru_index}([\:\) ])/) { "#{$1}#{array_index + 2}#{$2}"}
84
- end
85
- options[:using].gsub!(/index/) { 1 }
86
- options[:using].strip!
87
- else
88
- new_opt = (2...(2 + data.vectors.size)).to_a.join(':')
89
- options[:using] = "#{new_opt}:xtic(1)"
90
- end
91
- init_default(data, options)
92
- end
93
-
94
- ##
95
- # Method for inner use.
96
- def init_daru_vector(data, options)
97
- options[:using] ||= '2:xtic(1)'
98
- options[:title] ||= data.name
99
- init_default(data, options)
100
- end
101
-
102
- ##
103
- # Method for inner use.
104
- def init_default(data, file: false, **options)
105
- @type = :datablock
106
- @data = Datablock.new(data, file)
107
- @options = Hamster.hash(options)
53
+ # run method by name
54
+ send(INIT_HANDLERS[data.class], data, options)
108
55
  end
109
56
 
110
57
  ##
@@ -120,16 +67,7 @@ module GnuplotRB
120
67
  # Dataset.new(points, with: 'points', title: 'Points').to_s
121
68
  # #=> "$DATA1 with points title 'Points'"
122
69
  def to_s(terminal = nil)
123
- "#{@type == :datablock ? @data.name(terminal) : @data } #{options_to_string}"
124
- end
125
-
126
- ##
127
- # ====== Overview
128
- # Create string from own options
129
- def options_to_string
130
- options.sort_by { |key, _| OPTION_ORDER.find_index(key.to_s) || 999 }
131
- .map { |key, value| OptionHandling.option_to_string(key, value) }
132
- .join(' ')
70
+ "#{@type == :datablock ? @data.name(terminal) : @data} #{options_to_string}"
133
71
  end
134
72
 
135
73
  ##
@@ -145,18 +83,18 @@ module GnuplotRB
145
83
  # ====== Examples
146
84
  # Updating dataset with Math formula or filename given:
147
85
  # dataset = Dataset.new('file.data')
148
- # dataset.update('asd')
86
+ # dataset.update(data: 'asd')
149
87
  # #=> nothing updated
150
- # dataset.update('asd', title: 'File')
88
+ # dataset.update(data: 'asd', title: 'File')
151
89
  # #=> Dataset.new('file.data', title: 'File')
152
90
  # Updating dataset with data stored in Datablock:
153
91
  # in_memory_points = Dataset.new(points, title: 'Old one')
154
- # in_memory_points.update(some_update, title: 'Updated')
92
+ # in_memory_points.update(data: some_update, title: 'Updated')
155
93
  # #=> Dataset.new(points + some_update, title: 'Updated')
156
94
  # temp_file_points = Dataset.new(points, title: 'Old one', file: true)
157
- # temp_file_points.update(some_update)
95
+ # temp_file_points.update(data: some_update)
158
96
  # #=> data updated but no new dataset created
159
- # temp_file_points.update(some_update, title: 'Updated')
97
+ # temp_file_points.update(data: some_update, title: 'Updated')
160
98
  # #=> data updated and new dataset with title 'Updated' returned
161
99
  def update(data = nil, **options)
162
100
  if data && @type == :datablock
@@ -164,7 +102,7 @@ module GnuplotRB
164
102
  if new_datablock == @data
165
103
  update_options(options)
166
104
  else
167
- Dataset.new(@data.update(data), @options.merge(options))
105
+ self.class.new(new_datablock, options)
168
106
  end
169
107
  else
170
108
  update_options(options)
@@ -177,12 +115,29 @@ module GnuplotRB
177
115
  # data stored in datablock and calls super otherwise.
178
116
  def clone
179
117
  if @type == :datablock
180
- Dataset.new(@data, **@options)
118
+ new_with_options(@options)
181
119
  else
182
120
  super
183
121
  end
184
122
  end
185
123
 
124
+ ##
125
+ # ====== Overview
126
+ # Creates new Plot object with only one Dataset given - self.
127
+ # Calls #plot on created Plot. All arguments given to this #plot
128
+ # will be sent to Plot#plot instead.
129
+ # ====== Example
130
+ # sin = Dataset.new('sin(x)')
131
+ # sin.plot(term: [qt, size: [300, 300]])
132
+ # #=> shows qt window 300x300 with sin(x)
133
+ # sin.to_png('./plot.png')
134
+ # #=> creates png file with sin(x) plotted
135
+ def plot(*args)
136
+ Plot.new(self).plot(*args)
137
+ end
138
+
139
+ private
140
+
186
141
  ##
187
142
  # ====== Overview
188
143
  # Creates new dataset with existing options merged with
@@ -196,38 +151,74 @@ module GnuplotRB
196
151
  # #=> Dataset.new('file.data', title: 'File')
197
152
  def update_options(**options)
198
153
  if options.empty?
199
- return self
154
+ self
200
155
  else
201
- Dataset.new(@data, @options.merge(options))
156
+ new_with_options(@options.merge(options))
202
157
  end
203
158
  end
204
159
 
205
160
  ##
206
- # Method for inner use.
161
+ # ====== Overview
162
+ # Create string from own options
163
+ def options_to_string
164
+ options.sort_by { |key, _| OPTION_ORDER.find_index(key.to_s) || 999 }
165
+ .map { |key, value| OptionHandling.option_to_string(key, value) }
166
+ .join(' ')
167
+ end
168
+
169
+ ##
207
170
  # Needed by OptionHandling to create new object when
208
171
  # options are changed.
209
172
  def new_with_options(options)
210
173
  self.class.new(@data, options)
211
174
  end
212
175
 
213
- ##
214
- # ====== Overview
215
- # You may set options using #option_name(option_value) method.
216
- # A new object will be constructed with selected option set.
217
- # And finally you can get current value of any option using
218
- # #options_name without arguments.
219
- # ====== Examples
220
- # dataset = Dataset.new('file.data')
221
- # dataset.title #=> nil
222
- # new_dataset = dataset.title('Awesome plot')
223
- # dataset.title #=> nil
224
- # new_dataset.title #=> 'Awesome plot'
225
- def method_missing(meth_id, *args)
226
- option(meth_id, *args)
176
+ def init_string(data, options)
177
+ @type, @data = File.exist?(data) ? [:datafile, "'#{data}'"] : [:math_function, data.clone]
178
+ @options = Hamster.hash(options)
179
+ end
180
+
181
+ def init_dblock(data, options)
182
+ @type = :datablock
183
+ @data = data.clone
184
+ @options = Hamster.hash(options)
227
185
  end
228
186
 
229
- private :init_default,
230
- *INIT_HANDLERS.values,
231
- :new_with_options
187
+ def get_daru_columns(data, cnt)
188
+ new_opt = (2..cnt).to_a.join(':')
189
+ if data.index[0].is_a?(DateTime) || data.index[0].is_a?(Numeric)
190
+ "1:#{new_opt}"
191
+ else
192
+ "#{new_opt}:xtic(1)"
193
+ end
194
+ end
195
+
196
+ def init_daru_frame(data, options)
197
+ options[:title] ||= data.name
198
+ if options[:using]
199
+ options[:using] = " #{options[:using]} "
200
+ data.vectors.to_a.each_with_index do |daru_index, array_index|
201
+ options[:using].gsub!(/([\:\(\$ ])#{daru_index}([\:\) ])/) do
202
+ "#{Regexp.last_match(1)}#{array_index + 2}#{Regexp.last_match(2)}"
203
+ end
204
+ end
205
+ options[:using].gsub!('index', '1').strip!
206
+ else
207
+ options[:using] = get_daru_columns(data, data.vectors.size + 1)
208
+ end
209
+ init_default(data, options)
210
+ end
211
+
212
+ def init_daru_vector(data, options)
213
+ options[:using] ||= get_daru_columns(data, 2)
214
+ options[:title] ||= data.name
215
+ init_default(data, options)
216
+ end
217
+
218
+ def init_default(data, file: false, **options)
219
+ @type = :datablock
220
+ @data = Datablock.new(data, file)
221
+ @options = Hamster.hash(options)
222
+ end
232
223
  end
233
224
  end
@@ -7,59 +7,71 @@ module GnuplotRB
7
7
  # Since gem uses some modern gnuplot features it's
8
8
  # required to have modern gnuplot installed.
9
9
  MIN_GNUPLOT_VERSION = 5.0
10
- ##
11
- # ====== Overview
12
- # Get path that should be used to run gnuplot executable.
13
- # Default value: 'gnuplot'
14
- def self.gnuplot_path
15
- self.gnuplot_path = 'gnuplot' unless defined?(@gnuplot_path)
16
- @gnuplot_path
17
- end
18
10
 
19
- ##
20
- # ====== Overview
21
- # Set path to gnuplot executable.
22
- def self.gnuplot_path=(path)
23
- validate_version(path)
24
- opts = { stdin_data: "set term\n" }
25
- @available_terminals = Open3.capture2e(path, **opts)
26
- .first
27
- .scan(/[:\n] +([a-z][^ ]+)/)
28
- .map(&:first)
29
- @gnuplot_path = path
30
- end
11
+ class << self
12
+ ##
13
+ # Max fit dely is used inside fit function.
14
+ # If it waits for output more than max_fit_delay seconds
15
+ # this behaviour is considered as errorneus.
16
+ # For heavy calculations max_fit_delay may be increased.
17
+ attr_writer :max_fit_delay
18
+ def max_fit_delay
19
+ @max_fit_delay ||= 5
20
+ end
21
+ ##
22
+ # ====== Overview
23
+ # Get path that should be used to run gnuplot executable.
24
+ # Default value: 'gnuplot'
25
+ def gnuplot_path
26
+ self.gnuplot_path = 'gnuplot' unless defined?(@gnuplot_path)
27
+ @gnuplot_path
28
+ end
31
29
 
32
- ##
33
- # ====== Overview
34
- # Get list of terminals (png, html, qt, jpeg etc)
35
- # available for that gnuplot.
36
- def self.available_terminals
37
- gnuplot_path
38
- @available_terminals
39
- end
30
+ ##
31
+ # ====== Overview
32
+ # Set path to gnuplot executable.
33
+ def gnuplot_path=(path)
34
+ validate_version(path)
35
+ opts = { stdin_data: "set term\n" }
36
+ @available_terminals = Open3.capture2e(path, **opts)
37
+ .first
38
+ .scan(/[:\n] +([a-z][^ ]+)/)
39
+ .map(&:first)
40
+ @gnuplot_path = path
41
+ end
40
42
 
41
- ##
42
- # ====== Overview
43
- # Get gnuplot version. Uses gnuplot_path to find
44
- # gnuplot executable.
45
- def self.version
46
- gnuplot_path
47
- @version
48
- end
43
+ ##
44
+ # ====== Overview
45
+ # Get list of terminals (png, html, qt, jpeg etc)
46
+ # available for that gnuplot.
47
+ def available_terminals
48
+ gnuplot_path
49
+ @available_terminals
50
+ end
49
51
 
50
- ##
51
- # ====== Overview
52
- # Validates gnuplot version. Compares current gnuplot's
53
- # version with ::MIN_GNUPLOT_VERSION.
54
- # ====== Arguments
55
- # * *path* - path to gnuplot executable.
56
- def self.validate_version(path)
57
- @version = IO.popen("#{path} --version")
58
- .read
59
- .match(/gnuplot ([^ ]+)/)[1]
60
- .to_f
61
- message = "Your Gnuplot version is #{@version}, please update it to at least 5.0"
62
- fail(ArgumentError, message) if @version < MIN_GNUPLOT_VERSION
52
+ ##
53
+ # ====== Overview
54
+ # Get gnuplot version. Uses gnuplot_path to find
55
+ # gnuplot executable.
56
+ def version
57
+ gnuplot_path
58
+ @version
59
+ end
60
+
61
+ ##
62
+ # ====== Overview
63
+ # Validates gnuplot version. Compares current gnuplot's
64
+ # version with ::MIN_GNUPLOT_VERSION.
65
+ # ====== Arguments
66
+ # * *path* - path to gnuplot executable.
67
+ def validate_version(path)
68
+ @version = IO.popen("#{path} --version")
69
+ .read
70
+ .match(/gnuplot ([^ ]+)/)[1]
71
+ .to_f
72
+ message = "Your Gnuplot version is #{@version}, please update it to at least 5.0"
73
+ fail(ArgumentError, message) if @version < MIN_GNUPLOT_VERSION
74
+ end
63
75
  end
64
76
  end
65
77
  end
@@ -7,7 +7,7 @@ module GnuplotRB
7
7
  # to gnuplot as 'set key value'.
8
8
  class Terminal
9
9
  include ErrorHandling
10
- OPTION_ORDER = [:term, :output, :multiplot]
10
+ OPTION_ORDER = [:term, :output, :multiplot, :timefmt, :xrange]
11
11
 
12
12
  class << self
13
13
  ##
@@ -35,7 +35,7 @@ module GnuplotRB
35
35
  @cmd += ' 2>&1'
36
36
  stream = IO.popen(@cmd, 'w+')
37
37
  handle_stderr(stream)
38
- ObjectSpace.define_finalizer(self, proc { Terminal::close_arg(stream) } )
38
+ ObjectSpace.define_finalizer(self, proc { Terminal.close_arg(stream) })
39
39
  @in = stream
40
40
  yield(self) if block_given?
41
41
  end
@@ -57,9 +57,9 @@ module GnuplotRB
57
57
  # #=> EOD
58
58
  def store_datablock(data)
59
59
  name = "$DATA#{@current_datablock += 1}"
60
- self.puts "#{name} << EOD"
61
- self.puts data
62
- self.puts 'EOD'
60
+ stream_puts "#{name} << EOD"
61
+ stream_puts data
62
+ stream_puts 'EOD'
63
63
  name
64
64
  end
65
65
 
@@ -98,7 +98,7 @@ module GnuplotRB
98
98
  # #=> outputs to gnuplot: "set term qt size 100,100\n"
99
99
  def set(options)
100
100
  OptionHandling.validate_terminal_options(options)
101
- self.puts(options_hash_to_string(options))
101
+ stream_puts(options_hash_to_string(options))
102
102
  end
103
103
 
104
104
  ##
@@ -109,7 +109,7 @@ module GnuplotRB
109
109
  def unset(*options)
110
110
  options.flatten
111
111
  .sort_by { |key| OPTION_ORDER.find_index(key) || -1 }
112
- .each { |key| self.puts "unset #{OptionHandling.string_key(key)}" }
112
+ .each { |key| stream_puts "unset #{OptionHandling.string_key(key)}" }
113
113
  self
114
114
  end
115
115
 
@@ -118,13 +118,10 @@ module GnuplotRB
118
118
  # Short way to plot Datablock, Plot or Splot object.
119
119
  # Other items will be just piped out to gnuplot.
120
120
  def <<(item)
121
- case item
122
- when Dataset
123
- Plot.new(item).plot(self)
124
- when Plottable
121
+ if item.is_a? Plottable
125
122
  item.plot(self)
126
123
  else
127
- self.print(item.to_s)
124
+ stream_print(item.to_s)
128
125
  end
129
126
  self
130
127
  end
@@ -133,15 +130,15 @@ module GnuplotRB
133
130
  # ====== Overview
134
131
  # Just puts *command* to gnuplot pipe and returns self
135
132
  # to allow chaining.
136
- def puts(command)
137
- self.print("#{command}\n")
133
+ def stream_puts(command)
134
+ stream_print("#{command}\n")
138
135
  end
139
136
 
140
137
  ##
141
138
  # ====== Overview
142
139
  # Just prints *command* to gnuplot pipe and returns self
143
140
  # to allow chaining.
144
- def print(command)
141
+ def stream_print(command)
145
142
  check_errors
146
143
  @in.print(command)
147
144
  self
@@ -153,7 +150,7 @@ module GnuplotRB
153
150
  # with rereading data.
154
151
  def replot(**options)
155
152
  set(options)
156
- self.puts('replot')
153
+ stream_puts('replot')
157
154
  unset(options.keys)
158
155
  sleep 0.01 until File.size?(options[:output]) if options[:output]
159
156
  self
@@ -165,7 +162,7 @@ module GnuplotRB
165
162
  # Closes pipe so Terminal object should not be used after #close call.
166
163
  def close
167
164
  check_errors
168
- Terminal::close_arg(@in)
165
+ Terminal.close_arg(@in)
169
166
  end
170
167
  end
171
168
  end
@@ -2,5 +2,5 @@
2
2
  # === Overview
3
3
  # Ruby bindings for gnuplot.
4
4
  module GnuplotRB
5
- VERSION = '0.2.0'
5
+ VERSION = '0.3.0'
6
6
  end
data/lib/gnuplotrb.rb CHANGED
@@ -1,13 +1,12 @@
1
1
  require 'tempfile'
2
2
  require 'hamster'
3
3
  require 'open3'
4
+ require 'base64'
4
5
 
5
6
  def require_if_available(name)
6
- begin
7
- require name
8
- rescue LoadError
9
- false
10
- end
7
+ require name
8
+ rescue LoadError
9
+ false
11
10
  end
12
11
 
13
12
  require_if_available('daru')
@@ -15,7 +14,6 @@ require_if_available('daru')
15
14
  require 'gnuplotrb/external_classes/string'
16
15
  require 'gnuplotrb/external_classes/array'
17
16
  require 'gnuplotrb/external_classes/daru'
18
- require 'gnuplotrb/external_classes/iruby'
19
17
 
20
18
  require 'gnuplotrb/version'
21
19
  require 'gnuplotrb/staff/settings'
@@ -25,6 +23,8 @@ require 'gnuplotrb/mixins/plottable'
25
23
  require 'gnuplotrb/staff/terminal'
26
24
  require 'gnuplotrb/staff/datablock'
27
25
  require 'gnuplotrb/staff/dataset'
26
+ require 'gnuplotrb/fit'
28
27
  require 'gnuplotrb/plot'
29
28
  require 'gnuplotrb/splot'
30
29
  require 'gnuplotrb/multiplot'
30
+ require 'gnuplotrb/animation'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gnuplotrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Evgrafov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-04 00:00:00.000000000 Z
11
+ date: 2015-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hamster
@@ -149,10 +149,11 @@ files:
149
149
  - Rakefile
150
150
  - gnuplotrb.gemspec
151
151
  - lib/gnuplotrb.rb
152
+ - lib/gnuplotrb/animation.rb
152
153
  - lib/gnuplotrb/external_classes/array.rb
153
154
  - lib/gnuplotrb/external_classes/daru.rb
154
- - lib/gnuplotrb/external_classes/iruby.rb
155
155
  - lib/gnuplotrb/external_classes/string.rb
156
+ - lib/gnuplotrb/fit.rb
156
157
  - lib/gnuplotrb/mixins/error_handling.rb
157
158
  - lib/gnuplotrb/mixins/option_handling.rb
158
159
  - lib/gnuplotrb/mixins/plottable.rb
@@ -1,18 +0,0 @@
1
- if defined?(IRuby)
2
- module GnuplotRB
3
- module Plottable
4
- def to_iruby
5
- available_terminals = {
6
- 'png' => 'image/png',
7
- 'pngcairo' => 'image/png',
8
- 'jpeg' => 'image/jpeg',
9
- 'svg' => 'image/svg+xml',
10
- 'dumb' => 'text/plain'
11
- }
12
- terminal, options = term.is_a?(Array) ? [term[0], term[1]] : [term, {}]
13
- terminal = 'svg' unless available_terminals.keys.include?(terminal)
14
- [available_terminals[terminal], self.send("to_#{terminal}".to_sym, **options)]
15
- end
16
- end
17
- end
18
- end