numo-gnuplot 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7a5482f076a126f3270d221c2ad38455ac266b6a
4
+ data.tar.gz: 1115269a4c0e558c2272f14b36e591e41d26bd28
5
+ SHA512:
6
+ metadata.gz: 0cb38d93f404dca82818117ae8f7620c160bbd3eb3e6f3abfcf3a2d9cd44b05d2d3a445b6f2592b6011446fd7038a0da6f4660131a659c1cefb976484e0f5161
7
+ data.tar.gz: 76b7602cd0fe6f0e23e5a62dddc01ff63cf5064ad54a5bf8a3d8594dfcec9d600990a81dc539c72cfc490ad0b3913220f1214ca70b94f734a4e1286b3c7a0742
@@ -0,0 +1,54 @@
1
+ *.gem
2
+ *.rbc
3
+ Gemfile.lock
4
+ InstalledFiles
5
+ SetupConfig
6
+ SetupReceipt
7
+ coverage
8
+ pkg/
9
+ spec/reports
10
+ spec/examples.txt
11
+ spec/*/*.dat
12
+ spec/*/*.csv
13
+ test/tmp
14
+ test/version_tmp
15
+ tmp/
16
+ .config
17
+ *~
18
+ */*~
19
+ */*/*~
20
+ *.bak
21
+ */*.bak
22
+ */*/*.bak
23
+ .#*
24
+ */.#*
25
+ */*/.#*
26
+ rhosts
27
+
28
+ ## Specific to RubyMotion:
29
+ .dat*
30
+ .repl_history
31
+ build/
32
+
33
+ ## Documentation cache and generated files:
34
+ .yardoc/
35
+ _yardoc/
36
+ doc/
37
+ rdoc/
38
+
39
+ ## Environment normalization:
40
+ .bundle/
41
+ /vendor/bundle
42
+ /lib/bundler/man/
43
+
44
+ # for a library or gem, you might want to ignore these files since the code is
45
+ # intended to run in multiple environments; otherwise, check them in:
46
+ # Gemfile.lock
47
+ # .ruby-version
48
+ # .ruby-gemset
49
+
50
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
51
+ .rvmrc
52
+
53
+ # examples
54
+ /examples/*.png
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in numo-gnuplot.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Masahiro TANAKA
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,153 @@
1
+ # Numo::Gnuplot : Gnuplot interface for Ruby
2
+
3
+ * Alpha version under development.
4
+ * [GitHub site](https://github.com/masa16/numo-gnuplot)
5
+
6
+ Although there are many [other Gnuplot interface libraries for Ruby](https://github.com/masa16/numo-gnuplot#related-work),
7
+ none of them have so simple interface as to obtain an XY data plot by just typing:
8
+
9
+ plot x,y
10
+
11
+ Numo::Gnuplot achieves this by providing only one class which has
12
+ the same inteface as Gnuplot command line, and no other class which
13
+ causes extra learning costs.
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'numo-gnuplot'
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Or install it yourself as:
28
+
29
+ $ gem install numo-gnuplot
30
+
31
+ ## Usage
32
+
33
+ * All examples require to load Numo::Gnuplot class:
34
+
35
+ ```ruby
36
+ require "numo/gnuplot"
37
+ ```
38
+
39
+ * The first example showing how it works.
40
+
41
+ ```ruby
42
+ gp = Numo::Gnuplot.new
43
+ gp.set title:"First Example"
44
+ gp.plot "sin(x)"
45
+ ```
46
+
47
+ * You can avoid receiver.
48
+
49
+ ```ruby
50
+ Numo::Gnuplot.new.instance_eval do
51
+ set title:"Second Example"
52
+ plot "sin(x)"
53
+ end
54
+ ```
55
+
56
+ * The same thing in short.
57
+
58
+ ```ruby
59
+ Numo.gnuplot do
60
+ set title:"Third Example"
61
+ plot "sin(x)"
62
+ end
63
+ ```
64
+
65
+ * Interactive plotting with IRB:
66
+
67
+ ```
68
+ $ irb -r numo/gnuplot
69
+ irb(main):001:0> pushb Numo.gnuplot
70
+ irb(gnuplot):002:0> set t:"Forth Example"
71
+ irb(gnuplot):003:0> plot "sin(x)"
72
+ ```
73
+
74
+ * Plotting X-Y data.
75
+
76
+ ```ruby
77
+ require "numo/gnuplot"
78
+
79
+ x = (0..100).map{|i| i*0.1}
80
+ y = x.map{|i| Math.sin(i)}
81
+
82
+ Numo.gnuplot do
83
+ set title:"X-Y data plot"
84
+ plot x,y, w:'lines', t:'sin(x)'
85
+ end
86
+ ```
87
+
88
+ * Plotting X-Y data in NArray.
89
+
90
+ ```ruby
91
+ require "numo/gnuplot"
92
+ require "numo/narray"
93
+
94
+ x = Numo::DFloat[0..100]/10
95
+ y = Numo::NMath.sin(x)
96
+
97
+ Numo.gnuplot do
98
+ set title:"X-Y data plot in Numo::NArray"
99
+ plot x,y, w:'lines', t:'sin(x)'
100
+ end
101
+ ```
102
+
103
+ * Multiple data are separated by Hash or put into Array.
104
+
105
+ ```ruby
106
+ require 'numo/gnuplot'
107
+ require 'numo/narray'
108
+ NM = Numo::NMath
109
+
110
+ n = 60
111
+ x = Numo::DFloat[-n..n]/n*10
112
+
113
+ Numo.gnuplot do
114
+ set title:"multiple data series"
115
+ # separate by Hash
116
+ plot x,NM.sin(x), {w:'points',t:'sin(x)'}, x,x*NM.sin(x),{w:"lines",t:'x*sin(x)'}
117
+ # or separate into Array
118
+ # plot [x,NM.sin(x), w:'points',t:'sin(x)'], [x,x*NM.sin(x),w:"lines",t:'x*sin(x)']
119
+ # (here last item in each Array should be Hash in order to distinguish from array data)
120
+ gets
121
+ end
122
+ ```
123
+
124
+ * Plotting 2D arrays in 3D.
125
+
126
+ ```ruby
127
+ require 'numo/gnuplot'
128
+ require 'numo/narray'
129
+
130
+ n = 60
131
+ x = (Numo::DFloat.new(1,n).seq/n-0.5)*30
132
+ y = (Numo::DFloat.new(n,1).seq/n-0.5)*30
133
+ r = Numo::NMath.sqrt(x**2+y**2) + 1e-10
134
+ z = Numo::NMath.sin(r)/r
135
+
136
+ Numo.gnuplot do
137
+ set title:'2D data plot'
138
+ set dgrid3d:[60,60]
139
+ splot z, w:'pm3d', t:'sin(r)/r'
140
+ end
141
+ ```
142
+
143
+ ## Related Work
144
+
145
+ * [Ruby Gnuplot](https://github.com/rdp/ruby_gnuplot/tree/master)
146
+ * [GNUPlotr](https://github.com/pbosetti/gnuplotr)
147
+ * [GnuPlotter](https://github.com/maasha/gnuplotter)
148
+ * [GnuplotRB](https://github.com/dilcom/gnuplotrb)
149
+
150
+ ## Contributing
151
+
152
+ Bug reports and pull requests are welcome on GitHub at
153
+ https://github.com/[USERNAME]/numo-gnuplot.
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,20 @@
1
+ require "numo/gnuplot"
2
+
3
+ gp = Numo.gnuplot
4
+
5
+ puts "mouse/key on window to continue"
6
+ Dir.glob("ex*.rb") do |frb|
7
+ gp.reset
8
+ load frb
9
+ gp.pause mouse:"any"
10
+ end
11
+
12
+ gp.set term:"png"
13
+
14
+ Dir.glob("ex*.rb") do |frb|
15
+ fimg = File.basename(frb,".rb")+".png"
16
+ gp.reset
17
+ gp.set output:fimg
18
+ load frb
19
+ puts "wrote #{fimg}"
20
+ end
@@ -0,0 +1,7 @@
1
+ Numo.gnuplot do
2
+ set xrange:-5..10
3
+ set title:'Math function example'
4
+ set xlabel:'x'
5
+ set ylabel:'y'
6
+ plot 'x*sin(x)', with:'lines', lt:{rgb:'blue',lw:3}
7
+ end
@@ -0,0 +1,11 @@
1
+ # X-Y data plot
2
+
3
+ x = 20.times.map{|i| i*0.5}
4
+ y = x.map{|i| i*Math.sin(i)}
5
+
6
+ Numo.gnuplot do
7
+ set title:'X-Y data plot example'
8
+ set xlabel:'x'
9
+ set ylabel:'y'
10
+ plot x,y, with:'lp', lt:{rgb:'blue',lw:3}
11
+ end
@@ -0,0 +1,10 @@
1
+ require 'numo/narray'
2
+
3
+ # X-Y data plot with Numo::NArray
4
+ x = Numo::DFloat[0..100]/10
5
+ y = Numo::NMath.sin(x)
6
+
7
+ Numo.gnuplot do
8
+ set title:"X-Y data plot with Numo::NArray"
9
+ plot x,y, w:'lines', t:'sin(x)'
10
+ end
@@ -0,0 +1,6 @@
1
+ # multiple function plot (Array separated)
2
+
3
+ Numo.gnuplot do
4
+ set title:"Multiple function plot"
5
+ plot ['sin(x)', w:"lp"],['x*sin(x)',w:"lines"]
6
+ end
@@ -0,0 +1,11 @@
1
+ require 'numo/narray'
2
+
3
+ # multiple data series plot (Hash separated)
4
+ n = 60
5
+ x = Numo::DFloat[-n..n]/n*10
6
+ nm = Numo::NMath
7
+
8
+ Numo.gnuplot do
9
+ set title:"multiple data series plot"
10
+ plot x,nm.sin(x), {w:'points',t:'sin(x)'}, x,x*nm.sin(x),{w:"lines",t:'x*sin(x)'}
11
+ end
@@ -0,0 +1,14 @@
1
+ require "numo/narray"
2
+
3
+ # 3D plot of 2D data with Numo::NArray
4
+ n = 60
5
+ x = (Numo::DFloat.new(1,n).seq/n-0.5)*30
6
+ y = (Numo::DFloat.new(n,1).seq/n-0.5)*30
7
+ r = Numo::NMath.sqrt(x**2+y**2) + 1e-10
8
+ z = Numo::NMath.sin(r)/r
9
+
10
+ Numo.gnuplot do
11
+ set title:'3D plot of 2D data'
12
+ set dgrid3d:[60,60]
13
+ splot z, w:'pm3d', t:'sin(r)/r'
14
+ end
@@ -0,0 +1,22 @@
1
+ require "numo/narray"
2
+
3
+ # 3D plot of XYZ data with Numo::NArray
4
+ df = Numo::DFloat
5
+ nm = Numo::NMath
6
+ n = 120
7
+ x = (df.new(1,n).seq/n-0.5)*30
8
+ y = (df.new(n,1).seq/n-0.5)*30
9
+ r = nm.sqrt(x**2+y**2) + 1e-10
10
+ z = nm.sin(r)/r
11
+ x += df.zeros(n,1)
12
+ y += df.zeros(1,n)
13
+
14
+ Numo.gnuplot do
15
+ set title:'3D plot of XYZ data',
16
+ palette:{rgbformula:[22,13,-31]},
17
+ dgrid3d:[60,60],
18
+ xlabel:'x',
19
+ ylabel:'y',
20
+ zlabel:'sin(r)/r'
21
+ splot x,y,z, w:'pm3d', t:'sin(r)/r'
22
+ end
@@ -0,0 +1,493 @@
1
+ module Numo
2
+
3
+ def gnuplot(&block)
4
+ if block
5
+ Gnuplot.default.instance_eval(&block)
6
+ else
7
+ Gnuplot.default
8
+ end
9
+ end
10
+ module_function :gnuplot
11
+
12
+ class Gnuplot
13
+
14
+ VERSION = "0.1.0"
15
+ POOL = []
16
+ DATA_FORMAT = "%.5g"
17
+
18
+ class GnuplotError < StandardError; end
19
+
20
+ def self.default
21
+ POOL[0] ||= self.new
22
+ end
23
+
24
+ def initialize(gnuplot_command="gnuplot")
25
+ @history = []
26
+ @iow = IO.popen(gnuplot_command+" 2>&1","w+")
27
+ @ior = @iow
28
+ @gnuplot_version = send_cmd("print GPVAL_VERSION")[0].chomp
29
+ @debug = false
30
+ end
31
+
32
+ attr_reader :history
33
+ attr_reader :gnuplot_version
34
+
35
+ # draw 2D functions and data.
36
+ def plot(*args)
37
+ _plot_splot("plot",args)
38
+ nil
39
+ end
40
+
41
+ # draws 2D projections of 3D surfaces and data.
42
+ def splot(*args)
43
+ _plot_splot("splot",args)
44
+ nil
45
+ end
46
+
47
+ def _plot_splot(cmd,args)
48
+ contents = parse_plot_args(args)
49
+ r = contents.shift.map{|x|"[#{x.begin}:#{x.end}] "}.join
50
+ c = contents.map{|x| x.cmd_str}.join(",")
51
+ d = contents.map{|x| x.data_str}.join
52
+ run "#{cmd} #{r}#{c}\n#{d}"
53
+ nil
54
+ end
55
+ private :_plot_splot
56
+
57
+ # replot is not recommended, use refresh
58
+ def replot
59
+ run "replot\n#{@last_data}"
60
+ nil
61
+ end
62
+
63
+ # The `set` command is used to set _lots_ of options.
64
+ def set(*args)
65
+ _set_unset("set",args)
66
+ nil
67
+ end
68
+
69
+ # The `unset` command is used to return to their default state.
70
+ def unset(*args)
71
+ _set_unset("unset",args)
72
+ nil
73
+ end
74
+
75
+ def _set_unset(cmd,args)
76
+ args.each do |a|
77
+ case a
78
+ when Hash
79
+ a.each do |k,v|
80
+ run "#{cmd} #{KvItem.new(k,v)}"
81
+ end
82
+ else
83
+ run "#{cmd} #{a}"
84
+ end
85
+ end
86
+ nil
87
+ end
88
+ private :_set_unset
89
+
90
+ # The `help` command displays built-in help.
91
+ def help(s=nil)
92
+ puts send_cmd "help #{s}\n\n"
93
+ end
94
+
95
+ # The `show` command shows their settings.
96
+ def show(x)
97
+ puts send_cmd "show #{x}"
98
+ end
99
+
100
+ # The `reset` command causes all graph-related options that can be
101
+ # set with the `set` command to take on their default values.
102
+ def reset(x=nil)
103
+ run "reset #{x}"
104
+ nil
105
+ end
106
+
107
+ # The `pause` command used to wait for events on window.
108
+ # Carriage return entry (-1 is given for argument) and
109
+ # text display option is disabled.
110
+ # pause 10
111
+ # pause 'mouse'
112
+ # pause mouse:%w[keypress,button1,button2,button3,close,any]
113
+ def pause(*args)
114
+ send_cmd("pause #{OptsToS.new(*args)}").join.chomp
115
+ nil
116
+ end
117
+
118
+ # The `load` command executes each line of the specified input file.
119
+ def load(filename)
120
+ send_cmd "load '#{filename}'"
121
+ nil
122
+ end
123
+
124
+ alias kernel_raise :raise
125
+
126
+ # The `raise` command raises plot window(s)
127
+ def raise_plot(plot_window_nb=nil)
128
+ send_cmd "raise #{plot_window_nb}"
129
+ nil
130
+ end
131
+ alias raise :raise_plot
132
+
133
+ # The `lower` command lowers plot window(s)
134
+ def lower_plot(plot_window_nb=nil)
135
+ send_cmd "lower #{plot_window_nb}"
136
+ nil
137
+ end
138
+ alias lower :lower_plot
139
+
140
+ # The `clear` command erases the current screen or output device as specified
141
+ # by `set output`. This usually generates a formfeed on hardcopy devices.
142
+ def clear
143
+ send_cmd "clear"
144
+ nil
145
+ end
146
+
147
+ # The `exit` and `quit` commands will exit `gnuplot`.
148
+ def exit
149
+ send_cmd "exit"
150
+ nil
151
+ end
152
+
153
+ # The `exit` and `quit` commands will exit `gnuplot`.
154
+ def quit
155
+ send_cmd "quit"
156
+ nil
157
+ end
158
+
159
+ # The `refresh` reformats and redraws the current plot using the
160
+ # data already read in.
161
+ def refresh
162
+ send_cmd "reflesh"
163
+ nil
164
+ end
165
+
166
+ # `var` returns Gnuplot variable (not Gnuplot command)
167
+ def var(name)
168
+ res = send_cmd("print #{name}").join("").chomp
169
+ if /undefined variable:/ =~ res
170
+ kernel_raise GnuplotError,res.strip
171
+ end
172
+ res
173
+ end
174
+
175
+ # turn on debug
176
+ def debug_on
177
+ @debug = true
178
+ end
179
+
180
+ # turn off debug
181
+ def debug_off
182
+ @debug = false
183
+ end
184
+
185
+ #other_commands = %w[
186
+ # bind
187
+ # call
188
+ # cd
189
+ # do
190
+ # evaluate
191
+ # fit
192
+ # history
193
+ # if
194
+ # print
195
+ # pwd
196
+ # reread
197
+ # save
198
+ # shell
199
+ # stats
200
+ # system
201
+ # test
202
+ # update
203
+ # while
204
+ #]
205
+
206
+ # for irb workspace name
207
+ def to_s
208
+ "gnuplot"
209
+ end
210
+
211
+ def run(s)
212
+ res = send_cmd(s)
213
+ if !res.empty?
214
+ if res.size > 7
215
+ msg = "\n"+res[0..5].join("")+" :\n"
216
+ else
217
+ msg = "\n"+res.join("")
218
+ end
219
+ kernel_raise GnuplotError,msg
220
+ end
221
+ nil
222
+ end
223
+ private :run
224
+
225
+ def send_cmd(s)
226
+ puts "<"+s if @debug
227
+ @iow.puts s
228
+ @iow.flush
229
+ @iow.puts "print '_end_of_cmd_'"
230
+ @iow.flush
231
+ @history << s
232
+ res = []
233
+ while line=@ior.gets
234
+ puts ">"+line if @debug
235
+ break if /^_end_of_cmd_$/ =~ line
236
+ res << line
237
+ end
238
+ res # = res.chomp.strip
239
+ end
240
+ private :send_cmd
241
+
242
+ def parse_plot_args(args)
243
+ list = [[]]
244
+ item = PlotItem.new
245
+ list << item
246
+ args.each do |arg|
247
+ case arg
248
+ when Range
249
+ list.first << arg
250
+ when Array
251
+ if arg.all?{|e| e.kind_of?(Range)}
252
+ list.first.concat(arg)
253
+ elsif PlotItem.is_data(arg)
254
+ item << arg
255
+ else
256
+ if list.last.empty?
257
+ list.pop
258
+ end
259
+ item = PlotItem.new(*arg)
260
+ list << item
261
+ end
262
+ when Hash
263
+ item << arg
264
+ item = PlotItem.new
265
+ list << item
266
+ else
267
+ item << arg
268
+ end
269
+ end
270
+ if list.last.empty?
271
+ list.pop
272
+ end
273
+ return list
274
+ end
275
+ private :parse_plot_args
276
+
277
+
278
+ # @private
279
+ class OptsToS # :nodoc: all
280
+ def initialize(*opts)
281
+ @opts = opts
282
+ end
283
+
284
+ def to_s
285
+ opts_to_s(*@opts)
286
+ end
287
+
288
+ def opts_to_s(*opts)
289
+ #p opts
290
+ sep = ","
291
+ opts.map do |opt|
292
+ sep = " " if !opt.kind_of?(Numeric)
293
+ case opt
294
+ when Array
295
+ opt.map{|v| "#{opts_to_s(*v)}"}.join(sep)
296
+ when Hash
297
+ opt.map{|k,v| KvItem.new(k,v).to_s}.compact.join(" ")
298
+ when Range
299
+ "[#{opt.begin}:#{opt.end}]"
300
+ else
301
+ opt.to_s
302
+ end
303
+ end.join(sep)
304
+ end
305
+ end
306
+
307
+ # @private
308
+ class KvItem # :nodoc: all
309
+ NEED_QUOTE = %w[
310
+ background
311
+ cblabel
312
+ clabel
313
+ dashtype
314
+ dt
315
+ font
316
+ format
317
+ format_cb
318
+ format_x
319
+ format_x2
320
+ format_xy
321
+ format_y
322
+ format_y2
323
+ format_z
324
+ output
325
+ rgb
326
+ timefmt
327
+ title
328
+ x2label
329
+ xlabel
330
+ y2label
331
+ ylabel
332
+ zlabel
333
+ ].map{|x| x.to_sym}
334
+
335
+ def initialize(k,v)
336
+ @k = k
337
+ @v = v
338
+ end
339
+
340
+ def need_quote?(k)
341
+ NEED_QUOTE.any? do |q|
342
+ /^#{k}/ =~ q
343
+ end
344
+ end
345
+
346
+ def to_s
347
+ kv_to_s(@k,@v)
348
+ end
349
+
350
+ def kv_to_s(k,v)
351
+ if need_quote?(k)
352
+ case v
353
+ when String
354
+ "#{k} #{v.inspect}"
355
+ when Array
356
+ "#{k} #{v[0].inspect} #{OptsToS.new(*v[1..-1])}"
357
+ end
358
+ else
359
+ case v
360
+ when String
361
+ "#{k} #{v}"
362
+ when TrueClass
363
+ "#{k}"
364
+ when NilClass
365
+ nil
366
+ when FalseClass
367
+ nil
368
+ when Array
369
+ "#{k} #{OptsToS.new(*v)}"
370
+ else
371
+ "#{k} #{OptsToS.new(v)}"
372
+ end
373
+ end
374
+ end
375
+ end # KvItem
376
+
377
+
378
+ # @private
379
+ class PlotItem # :nodoc: all
380
+
381
+ def self.is_data(a)
382
+ if a.kind_of? Array
383
+ if a.last.kind_of?(Hash)
384
+ return false
385
+ else
386
+ t = a.first.class
387
+ t = Numeric if t < Numeric
388
+ return a.all?{|e| e.kind_of?(t)}
389
+ end
390
+ elsif defined?(Numo::NArray)
391
+ return true if a.kind_of?(Numo::NArray)
392
+ elsif defined?(NArray)
393
+ return true if a.kind_of?(NArray)
394
+ elsif defined?(NMatrix)
395
+ return true if a.kind_of?(NMatix)
396
+ end
397
+ false
398
+ end
399
+
400
+ def initialize(*items)
401
+ @items = items
402
+ end
403
+
404
+ def <<(item)
405
+ @items << item
406
+ end
407
+
408
+ def empty?
409
+ @items.empty?
410
+ end
411
+
412
+ def parse_items
413
+ if !@options
414
+ if @items.empty?
415
+ return
416
+ elsif @items.first.kind_of? String
417
+ @function = @items.first
418
+ @options = @items[1..-1]
419
+ else
420
+ @data = []
421
+ @options = []
422
+ @items.each do |x|
423
+ if PlotItem.is_data(x)
424
+ @data << x
425
+ else
426
+ @options << x
427
+ end
428
+ end
429
+ if @data.size==1
430
+ a = @data[0]
431
+ if a.respond_to?(:shape)
432
+ if a.shape.size == 2
433
+ @matrix = true
434
+ end
435
+ end
436
+ end
437
+ end
438
+ end
439
+ end
440
+
441
+ def cmd_str
442
+ parse_items
443
+ if @function
444
+ "%s %s" % [@function, OptsToS.new(*@options)]
445
+ else
446
+ if @matrix
447
+ "'-' matrix %s" % OptsToS.new(*@options)
448
+ else
449
+ "'-' %s" % OptsToS.new(*@options)
450
+ end
451
+ end
452
+ end
453
+
454
+ def data_str
455
+ parse_items
456
+ if @function
457
+ nil
458
+ else
459
+ if @matrix
460
+ data2d_to_s(@data[0])+"\ne\n"
461
+ else
462
+ data1d_to_s(@data)+"e\n"
463
+ end
464
+ end
465
+ end
466
+
467
+ def data_format
468
+ @data_format || DATA_FORMAT
469
+ end
470
+
471
+ def data_format=(s)
472
+ @data_format = s
473
+ end
474
+
475
+ def data1d_to_s(a)
476
+ n = a.map{|e| e.size}.min
477
+ f = ([data_format]*a.size).join(" ")+"\n"
478
+ s = ""
479
+ n.times{|i| s << f % a.map{|e| e[i]}}
480
+ s
481
+ end
482
+
483
+ def data2d_to_s(a)
484
+ f = data_format
485
+ s = ""
486
+ a.to_a.each do |b|
487
+ s << b.map{|e| f%e}.join(" ")+"\n"
488
+ end
489
+ s
490
+ end
491
+ end # PlotItem
492
+ end # Numo::Gnuplot
493
+ end