carray 1.3.7 → 1.4.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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -7
  3. data/Rakefile +31 -0
  4. data/carray.gemspec +9 -14
  5. data/carray.h +4 -0
  6. data/carray_access.c +50 -8
  7. data/carray_conversion.c +3 -3
  8. data/carray_generate.c +67 -1
  9. data/carray_math.rb +22 -22
  10. data/carray_operator.c +23 -0
  11. data/devel/im2col.rb +17 -0
  12. data/lib/carray.rb +32 -1
  13. data/lib/carray/autoload/autoload_base.rb +0 -4
  14. data/lib/carray/autoload/autoload_gem_cairo.rb +9 -0
  15. data/lib/carray/autoload/autoload_gem_ffi.rb +9 -0
  16. data/lib/carray/autoload/autoload_gem_gnuplot.rb +2 -0
  17. data/lib/carray/autoload/autoload_gem_io_csv.rb +14 -0
  18. data/lib/carray/autoload/autoload_gem_io_pg.rb +6 -0
  19. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +12 -0
  20. data/lib/carray/autoload/autoload_gem_narray.rb +10 -0
  21. data/lib/carray/autoload/autoload_gem_numo_narray.rb +14 -0
  22. data/lib/carray/autoload/autoload_gem_opencv.rb +16 -0
  23. data/lib/carray/autoload/autoload_gem_rmagick.rb +23 -0
  24. data/lib/carray/autoload/{autoload_graphics_zimg.rb → autoload_gem_zimg.rb} +0 -0
  25. data/lib/carray/base/autoload.rb +47 -5
  26. data/lib/carray/base/basic.rb +58 -2
  27. data/lib/carray/base/math.rb +1 -1
  28. data/lib/carray/base/string.rb +242 -0
  29. data/mkmath.rb +12 -2
  30. data/version.h +5 -5
  31. metadata +29 -109
  32. data/Gemfile +0 -8
  33. data/Gemfile.lock +0 -33
  34. data/ext/calculus/lib/autoload/autoload_math_calculus.rb +0 -2
  35. data/ext/fortio/extconf.rb +0 -3
  36. data/ext/fortio/lib/carray/autoload/autoload_fortran_format.rb +0 -5
  37. data/ext/fortio/lib/carray/io/fortran_format.rb +0 -43
  38. data/ext/fortio/lib/fortio.rb +0 -3
  39. data/ext/fortio/lib/fortio/fortran_format.rb +0 -605
  40. data/ext/fortio/lib/fortio/fortran_format.tab.rb +0 -536
  41. data/ext/fortio/lib/fortio/fortran_format.y +0 -215
  42. data/ext/fortio/lib/fortio/fortran_namelist.rb +0 -151
  43. data/ext/fortio/lib/fortio/fortran_namelist.tab.rb +0 -470
  44. data/ext/fortio/lib/fortio/fortran_namelist.y +0 -213
  45. data/ext/fortio/lib/fortio/fortran_sequential.rb +0 -345
  46. data/ext/fortio/ruby_fortio.c +0 -182
  47. data/ext/fortio/test/test_H.rb +0 -5
  48. data/ext/fortio/test/test_T.rb +0 -7
  49. data/ext/fortio/test/test_fortran_format.rb +0 -86
  50. data/ext/fortio/test/test_namelist.rb +0 -25
  51. data/ext/fortio/test/test_namelist_write.rb +0 -10
  52. data/ext/fortio/test/test_sequential.rb +0 -13
  53. data/ext/fortio/test/test_sequential2.rb +0 -13
  54. data/ext/fortio/work/test.rb +0 -10
  55. data/ext/fortio/work/test_e.rb +0 -19
  56. data/ext/fortio/work/test_ep.rb +0 -10
  57. data/ext/fortio/work/test_parse.rb +0 -12
  58. data/ext/mathfunc/lib/autoload/autoload_math_mathfunc.rb +0 -1
  59. data/ext/mathfunc/lib/math/mathfunc.rb +0 -15
  60. data/ext/narray/README +0 -22
  61. data/ext/narray/ca_wrap_narray.c +0 -500
  62. data/ext/narray/carray_narray.c +0 -21
  63. data/ext/narray/extconf.rb +0 -57
  64. data/ext/narray/lib/autoload/autoload_math_narray.rb +0 -1
  65. data/ext/narray/lib/autoload/autoload_math_narray_miss.rb +0 -11
  66. data/ext/narray/lib/math/narray.rb +0 -17
  67. data/ext/narray/lib/math/narray_miss.rb +0 -45
  68. data/lib/carray/autoload/autoload_graphics_gnuplot.rb +0 -2
  69. data/lib/carray/autoload/autoload_io_csv.rb +0 -14
  70. data/lib/carray/autoload/autoload_io_numo.rb +0 -9
  71. data/lib/carray/autoload/autoload_io_pg.rb +0 -6
  72. data/lib/carray/autoload/autoload_io_sqlite3.rb +0 -12
  73. data/lib/carray/graphics/gnuplot.rb +0 -2141
  74. data/lib/carray/graphics/zimg.rb +0 -296
  75. data/lib/carray/io/csv.rb +0 -572
  76. data/lib/carray/io/numo.rb +0 -52
  77. data/lib/carray/io/pg.rb +0 -101
  78. data/lib/carray/io/sqlite3.rb +0 -215
@@ -1,21 +0,0 @@
1
- /* ---------------------------------------------------------------------------
2
-
3
- carray/carray_narray.c
4
-
5
- This file is part of Ruby/CArray extension library.
6
- You can redistribute it and/or modify it under the terms of
7
- the Ruby Licence.
8
-
9
- Copyright (C) 2005 Hiroki Motoyoshi
10
-
11
- ---------------------------------------------------------------------------- */
12
-
13
- #include "ruby.h"
14
-
15
- void Init_ca_wrap_narray();
16
-
17
- void
18
- Init_carray_narray ()
19
- {
20
- Init_ca_wrap_narray();
21
- }
@@ -1,57 +0,0 @@
1
- require 'mkmf'
2
- require 'rbconfig'
3
- require_relative '../../lib/carray/mkmf'
4
-
5
- dir_config("carray", "../..", "../..")
6
-
7
- have_header("carray.h")
8
-
9
- if /cygwin|mingw/ =~ RUBY_PLATFORM
10
- have_library("carray")
11
- end
12
-
13
- # ---
14
-
15
- dir_config("narray", $sitearchdir, $sitearchdir)
16
-
17
- if defined? Gem
18
- if Gem::VERSION >= "1.7.0"
19
- begin
20
- Gem::Specification.find_all_by_name("narray").each do |spec|
21
- dir = spec.full_gem_path
22
- dir_config("narray", dir, dir)
23
- dir_config("narray", File.join(dir,"src"), File.join(dir,"src"))
24
- end
25
- rescue Gem::LoadError
26
- end
27
- else
28
- Gem.all_load_paths.grep(/narray/).each do |dir|
29
- dir_config("narray", dir, dir)
30
- dir_config("narray", File.join(dir,"src"), File.join(dir,"src"))
31
- end
32
- end
33
- end
34
-
35
- if have_header("narray.h")
36
- if /cygwin|mingw/ =~ RUBY_PLATFORM
37
- unless have_library("narray")
38
- open("Makefile", "w") { |io|
39
- io << "all:" << "\n"
40
- io << "install:" << "\n"
41
- io << "clean:" << "\n"
42
- io << "distclean:" << "\n"
43
- io << "\trm -rf mkmf.log Makefile" << "\n"
44
- }
45
- end
46
- end
47
- create_makefile("carray/carray_narray")
48
- else
49
- open("Makefile", "w") { |io|
50
- io << "all:" << "\n"
51
- io << "install:" << "\n"
52
- io << "clean:" << "\n"
53
- io << "distclean:" << "\n"
54
- io << "\trm -rf mkmf.log Makefile" << "\n"
55
- }
56
- end
57
-
@@ -1 +0,0 @@
1
- require "carray/math/narray"
@@ -1,11 +0,0 @@
1
-
2
- class CArray
3
- nam_rb = "carray/math/narray_miss"
4
- autoload_method :to_nam, nam_rb
5
- autoload_method :to_nam!, nam_rb
6
- end
7
-
8
- class NArrayMiss
9
- nam_rb = "carray/math/narray_miss"
10
- autoload_method :to_ca, nam_rb
11
- end
@@ -1,17 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- #
3
- # carray/math/narray.rb
4
- #
5
- # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
- #
9
- # Copyright (C) 2005 Hiroki Motoyoshi
10
- #
11
- # ----------------------------------------------------------------------------
12
-
13
- begin
14
- require "narray"
15
- require "carray/carray_narray"
16
- rescue LoadError, TypeError
17
- end
@@ -1,45 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- #
3
- # carray/math/narray_miss.rb
4
- #
5
- # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
- #
9
- # Copyright (C) 2005 Hiroki Motoyoshi
10
- #
11
- # ----------------------------------------------------------------------------
12
-
13
- require "narray_miss"
14
-
15
- class CArray
16
-
17
- def to_nam
18
- if has_mask?
19
- return NArrayMiss.to_nam_no_dup(to_na, mask.bit_neg.na)
20
- else
21
- return NArrayMiss.to_nam_no_dup(to_na)
22
- end
23
- end
24
-
25
- def to_nam!
26
- if has_mask?
27
- return NArrayMiss.to_nam_no_dup(to_na!, mask.bit_neg.to_na!)
28
- else
29
- return NArrayMiss.to_nam_no_dup(to_na!)
30
- end
31
- end
32
-
33
- end
34
-
35
- class NArrayMiss
36
-
37
- def to_ca
38
- ca = @array.to_ca
39
- ca.mask = @mask.ca
40
- ca.mask.bit_neg!
41
- return ca
42
- end
43
-
44
- end
45
-
@@ -1,2 +0,0 @@
1
- autoload_method "CA.gnuplot", "carray/graphics/gnuplot"
2
-
@@ -1,14 +0,0 @@
1
- autoload_method "CArray.load_csv", "carray/io/csv"
2
- autoload_method "CArray.from_csv", "carray/io/csv"
3
-
4
- class CArray
5
- autoload_method "save_csv", "carray/io/csv"
6
- autoload_method "to_csv", "carray/io/csv"
7
- autoload_method "to_tabular", "carray/io/csv"
8
- end
9
-
10
- module CA
11
- autoload :CSVReader, "carray/io/csv"
12
- autoload :CSVWriter, "carray/io/csv"
13
- end
14
-
@@ -1,9 +0,0 @@
1
- class CArray
2
- autoload_method "to_numo", "carray/io/numo"
3
- end
4
-
5
- module Numo
6
- class NArray
7
- autoload_method "to_ca", "carray/io/numo"
8
- end
9
- end
@@ -1,6 +0,0 @@
1
- autoload_method "CArray.load_pg", "carray/io/pg"
2
-
3
- class CArray
4
- autoload_method "unescape_bytea", "carray/io/pg"
5
- autoload_method "escape_bytea", "carray/io/pg"
6
- end
@@ -1,12 +0,0 @@
1
- autoload_method "CArray.load_sqlite3", "carray/io/sqlite3"
2
-
3
- class CArray
4
- autoload_method "unblob", "carray/io/sqlite3"
5
- autoload_method "to_sqlite3", "carray/io/sqlite3"
6
- end
7
-
8
- if Object.const_defined?(:SQLite3)
9
- require "carray/io/sqlite3"
10
- else
11
- autoload :SQLite3, "carray/io/sqlite3"
12
- end
@@ -1,2141 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- #
3
- # carray/graphics/gnuplot.rb
4
- #
5
- # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
- #
9
- # Copyright (C) 2005 Hiroki Motoyoshi
10
- #
11
- # ----------------------------------------------------------------------------
12
-
13
- require "date"
14
- require "time"
15
- require "open3"
16
- require "carray"
17
- require "ostruct"
18
-
19
- def CA.gnuplot (*argv, &block)
20
- CA::Gnuplot.new(*argv, &block)
21
- end
22
-
23
- class CA::Gnuplot # :nodoc:
24
-
25
- if File.directory?("/tmp")
26
- TMPDIR = "/tmp"
27
- else
28
- TMPDIR = "."
29
- end
30
-
31
- def initialize (command = "gnuplot", stdout: STDOUT, timezone: "", &block)
32
- begin
33
- @io, @stdout, @stderr = Open3.popen3(command + " -noraise")
34
- rescue NotImplementedError
35
- raise NotImplementedError, "system dosen't support Open3.popen3"
36
- end
37
-
38
- @defaults = {}
39
- @temp_file_count = 0
40
- @multiplot_mode = false
41
- @script_mode = false
42
- @pause_mode = :default
43
- @reset_mode = :default
44
- @init = nil
45
- @last = nil
46
- @listen = Thread.start {
47
- Thread.abort_on_exception = true
48
- begin
49
- stdout << @stdout.gets
50
- while line = @stdout.gets ### read(1024)
51
- # unless line =~ /\Agnuplot>/
52
- stdout << line
53
- stdout.flush
54
- # end
55
- end
56
- rescue IOError ### @stdout may externally closed
57
- end
58
- }
59
-
60
- @gnuplot_version = evaluate("GPVAL_VERSION").to_f
61
-
62
- epoch = evaluate %{strftime("%Y-%m-%d %H:%M:%S #{timezone}",0)}
63
- @EP_T = Time.parse(epoch)
64
- @EP_D = Date.parse(epoch)
65
- @EP_DT = DateTime.parse(epoch)
66
-
67
- @reset_script = reset_script() ## RESET_SCRIPT
68
-
69
- reset
70
- if block_given?
71
- begin
72
- case block.arity
73
- when 1
74
- yield(self)
75
- when -1, 0
76
- instance_exec(&block)
77
- else
78
- raise "invalid # of block parameters"
79
- end
80
- ensure
81
- self.close
82
- end
83
- end
84
- end
85
-
86
- attr_accessor :debug, :script_mode
87
- attr_reader :multiplot_mode, :multiplot_option, :last
88
-
89
- def close
90
- put("quit")
91
- @io.close
92
- @listen.join
93
- @stdout.close
94
- @stderr.close
95
- end
96
-
97
- def put (*args)
98
- lines = args.map {|s| s.respond_to?(:to_gnuplot) ? s.to_gnuplot : s.to_s }
99
- command = lines.join("\n")
100
- if @debug
101
- STDERR.puts command
102
- end
103
- thread = Thread.start {
104
- begin
105
- size = command.size
106
- s = 0
107
- while s < size
108
- s += @io.write(command[s, 2048])
109
- end
110
- @io.puts
111
- @io.puts %{ print "SIGNAL FOR CA::Gnuplot" }
112
- @io.flush
113
- rescue Errno::EPIPE
114
- end
115
- }
116
- output = ""
117
- while line = @stderr.gets
118
- case line.chomp
119
- when /SIGNAL FOR CA::Gnuplot$/
120
- STDERR.print(output) if @debug and not output.empty?
121
- return output.chomp
122
- when / line \d+: (.*?) /
123
- if $1 =~ /warning:/
124
- output << line
125
- STDERR.print output
126
- next
127
- else
128
- output << line
129
- STDERR.print output
130
- raise "Gnuplot Processor Error"
131
- end
132
- else
133
- output << line
134
- end
135
- end
136
- ensure
137
- thread.join
138
- end
139
-
140
- def reset_script
141
- # TO BE COMENNTED OUT
142
- # set size ratio 0 1,1
143
- # set origin 0,0
144
- # set lmargin -1
145
- # set bmargin -1
146
- # set rmargin -1
147
- # set tmargin -1
148
- # set locale "ja_JP.UTF-8"
149
- # set decimalsign
150
- # set encoding
151
- # set loadpath
152
- # set fontpath
153
- # set psdir
154
- # set fit brief errorvariables nocovariancevariables errorscaling prescale nowrap
155
- script = put(%{ save set "|cat 1>&2" }).split($/)
156
- script.delete_if {|s| s =~ /^set size ratio/ }
157
- script.delete_if {|s| s =~ /^set origin/ }
158
- script.delete_if {|s| s =~ /^set .margin/ }
159
- script.delete_if {|s| s =~ /^set locale/ }
160
- script.delete_if {|s| s =~ /^set decimalsign/ }
161
- script.delete_if {|s| s =~ /^set encoding/ }
162
- script.delete_if {|s| s =~ /^set loadpath/ }
163
- script.delete_if {|s| s =~ /^set fontpath/ }
164
- script.delete_if {|s| s =~ /^set psdir/ }
165
- script.delete_if {|s| s =~ /^set fit/ }
166
- return script.join($/)
167
- end
168
-
169
- def debug_on
170
- self.debug = true
171
- end
172
-
173
- def debug_off
174
- self.debug = false
175
- end
176
-
177
- def init (&block)
178
- @init = block
179
- @init.call
180
- return @init
181
- end
182
-
183
- def set (*argv)
184
- put "set " + argv.map{|s| s.gsub(/\n/,'') }.join(" ")
185
- end
186
-
187
- def unset (*argv)
188
- put "unset " + argv.map{|s| s.gsub(/\n/,'') }.join(" ")
189
- end
190
-
191
- def evaluate (expr)
192
- return put("print #{expr}")
193
- end
194
-
195
- def color_style (fgcolor, bgcolor = nil, framecolor = nil, shadowcolor = nil)
196
- if fgcolor
197
- @defaults[:fgcolor] = fgcolor
198
- put %{ fgcolor = "#{fgcolor}" }
199
- end
200
- if bgcolor
201
- @defaults[:bgcolor] = bgcolor
202
- put %{ bgcolor = "#{bgcolor}" }
203
- end
204
- if framecolor
205
- @defaults[:framecolor] = framecolor
206
- put %{ framecolor = "#{framecolor}" }
207
- end
208
- if shadowcolor
209
- @defaults[:shadowcolor] = shadowcolor
210
- put %{ shadowcolor = "#{shadowcolor}" }
211
- end
212
- end
213
-
214
- def framecolor (spec)
215
- @defaults[:framecolor] = spec
216
- put %{ framecolor = "#{spec}" }
217
- end
218
-
219
- alias frame_color framecolor
220
-
221
- def shadowcolor (spec)
222
- @defaults[:shadowcolor] = spec
223
- put %{ shadowcolor = "#{spec}" }
224
- end
225
-
226
- alias shadow_color shadowcolor
227
-
228
- def bgcolor (spec)
229
- @defaults[:bgcolor] = spec
230
- put %{ bgcolor = "#{spec}" }
231
- end
232
-
233
- alias bg_color bgcolor
234
-
235
- def fgcolor (spec)
236
- @defaults[:fgcolor] = spec
237
- put %{ fgcolor = "#{spec}" }
238
- end
239
-
240
- alias fg_color fgcolor
241
-
242
- def color_scheme (*names)
243
- if @gnuplot_version >= 5.0
244
- case names.first
245
- when :keynote
246
- put %{
247
- set linetype 1 lc rgb "#BB2C2F"
248
- set linetype 2 lc rgb "#5E9648"
249
- set linetype 3 lc rgb "#2E578B"
250
- set linetype 4 lc rgb "#6F3B77"
251
- set linetype 5 lc rgb "#002C63"
252
- set linetype 6 lc rgb "#E6A03D"
253
- set linetype 7 lc rgb "#7D807E"
254
- set linetype 8 lc rgb "#1B0C00"
255
- set linetype cycle 8
256
- }
257
- when :grads
258
- put %{
259
- set linetype 2 lc rgb "#fa3c3c"
260
- set linetype 3 lc rgb "#00dc00"
261
- set linetype 4 lc rgb "#1e3cff"
262
- set linetype 5 lc rgb "#00c8c8"
263
- set linetype 6 lc rgb "#f00082"
264
- set linetype 7 lc rgb "#e6dc32"
265
- set linetype 8 lc rgb "#f08228"
266
- set linetype 9 lc rgb "#a000c8"
267
- set linetype 10 lc rgb "#a0e632"
268
- set linetype 11 lc rgb "#00a0ff"
269
- set linetype 12 lc rgb "#e6af2d"
270
- set linetype 13 lc rgb "#00d28c"
271
- set linetype 14 lc rgb "#8200dc"
272
- set linetype 15 lc rgb "#aaaaaa"
273
- set linetype cycle 15
274
- }
275
- when :podo
276
- set %{ colorsequence podo }
277
- when :classic
278
- set %{ colorsequence classic }
279
- when :default
280
- set %{ colorsequence default }
281
- else
282
- style = []
283
- names.each_with_index do |col, i|
284
- style << %{ set linetype #{i+1} lc rgb "#{col.to_s}"}
285
- end
286
- put style.join("\n")
287
- end
288
- else
289
- case names.first
290
- when :keynote
291
- put %{
292
- set style increment user
293
- set style line 1 lc rgb "#BB2C2F"
294
- set style line 2 lc rgb "#5E9648"
295
- set style line 3 lc rgb "#2E578B"
296
- set style line 4 lc rgb "#6F3B77"
297
- set style line 5 lc rgb "#002C63"
298
- set style line 6 lc rgb "#E6A03D"
299
- set style line 7 lc rgb "#7D807E"
300
- set style line 8 lc rgb "#1B0C00"
301
- }
302
- when :grads
303
- put %{
304
- set style increment user
305
- set style line 2 lc rgb "#fa3c3c"
306
- set style line 3 lc rgb "#00dc00"
307
- set style line 4 lc rgb "#1e3cff"
308
- set style line 5 lc rgb "#00c8c8"
309
- set style line 6 lc rgb "#f00082"
310
- set style line 7 lc rgb "#e6dc32"
311
- set style line 8 lc rgb "#f08228"
312
- set style line 9 lc rgb "#a000c8"
313
- set style line 10 lc rgb "#a0e632"
314
- set style line 11 lc rgb "#00a0ff"
315
- set style line 12 lc rgb "#e6af2d"
316
- set style line 13 lc rgb "#00d28c"
317
- set style line 14 lc rgb "#8200dc"
318
- set style line 15 lc rgb "#aaaaaa"
319
- }
320
- else
321
- style = ["set style increment user"]
322
- names.each_with_index do |col, i|
323
- style << %{ set style line #{i+1} lc rgb "#{col.to_s}"}
324
- end
325
- put style.join("\n")
326
- end
327
- end
328
- end
329
-
330
-
331
- def pause_mode (arg = nil)
332
- # :none - no pausing
333
- # :default - return on terminal
334
- # :mouse - mouse click on window
335
- # :keypress - keypress on window
336
- orig = @pause_mode
337
- if arg
338
- @pause_mode = arg
339
- else
340
- @pause_mode = :default
341
- end
342
- if block_given?
343
- begin
344
- yield
345
- ensure
346
- @pause_mode = orig
347
- end
348
- end
349
- end
350
-
351
- def pause (arg = -1)
352
- if @multiplot_mode
353
- return
354
- else
355
- case @pause_mode
356
- when :none
357
- return
358
- when :mouse
359
- pause_mouse
360
- when :keypress
361
- pause_keypress
362
- else # :key
363
- term = evaluate("GPVAL_TERM")
364
- case term
365
- when /x11/, /aqua/, /wxt/
366
- STDIN.gets
367
- end
368
- end
369
- end
370
- end
371
-
372
- def pause_mouse
373
- put "pause mouse"
374
- mx = evaluate "MOUSE_X"
375
- my = evaluate "MOUSE_Y"
376
- mk = evaluate "MOUSE_KEY"
377
- return [mx, my, mk]
378
- end
379
-
380
- def pause_keypress
381
- put "pause mouse keypress"
382
- mx = evaluate "MOUSE_X"
383
- my = evaluate "MOUSE_Y"
384
- mk = evaluate "MOUSE_KEY"
385
- return [mx, my, mk]
386
- end
387
-
388
- def reset_mode (arg = nil)
389
- orig = @reset_mode
390
- if arg
391
- @reset_mode = arg
392
- else
393
- @reset_mode = :default
394
- end
395
- if block_given?
396
- begin
397
- yield
398
- ensure
399
- @reset_mode = orig
400
- end
401
- end
402
- end
403
-
404
- def reset ()
405
- if @script_mode or @reset_mode == :none
406
- return
407
- end
408
- if @multiplot_mode and
409
- ( @multiplot_option[:layout] or @multiplot_option[:noreset] )
410
- put @reset_script
411
- put("set xyplane relative 0",
412
- "set key Left reverse noautotitle")
413
- else
414
- put "reset"
415
- put("set xyplane relative 0",
416
- "set key Left reverse noautotitle")
417
- end
418
- end
419
-
420
- def terminal (text)
421
- text = text.split("\n").map{|l| l.strip }.join(" ").strip
422
- put("set term #{text}")
423
- end
424
-
425
- def output (text)
426
- @output = text
427
- text = text.split("\n").map{|l| l.strip }.join(" ").strip
428
- put("set output '#{text}'")
429
- end
430
-
431
- def time (data, timezone = nil)
432
-
433
- if timezone
434
- epoch = evaluate %{strftime("%Y-%m-%d %H:%M:%S #{timezone}",0)}
435
- ep_t = Time.parse(epoch)
436
- ep_d = Date.parse(epoch)
437
- ep_dt = DateTime.parse(epoch)
438
- else
439
- ep_t = @EP_T
440
- ep_d = @EP_D
441
- ep_dt = @EP_DT
442
- end
443
-
444
- case data
445
- when Numeric
446
- data
447
- when String
448
- Time.parse(data) - @EP_T
449
- when Time
450
- data - ep_t
451
- when Date
452
- (data - ep_d)*86400
453
- when DateTime
454
- (data - ep_dt)*86400
455
- when CArray
456
- return data.convert(CA_DOUBLE){|x|
457
- case x
458
- when Numeric
459
- x
460
- when Time
461
- x - ep_t
462
- when Date
463
- (x - ep_d)*86400
464
- when DateTime
465
- (x - ep_dt)*86400
466
- when String
467
- Time.parse(x) - ep_t
468
- end
469
- }
470
- when Range
471
- time(data.first, timezone)..time(data.last, timezone)
472
- end
473
- end
474
-
475
- def csv (*args)
476
- list = []
477
- args.each do |arg|
478
- case arg
479
- when Array
480
- list.push(arg.to_ca)
481
- else
482
- list.push(arg)
483
- end
484
- end
485
- return CArray.join(:object, list).to_csv
486
- end
487
-
488
- private
489
-
490
- def with_tempfile (nfiles=1)
491
- tempfile = Array.new(nfiles) {
492
- @temp_file_count += 1
493
- File.join(TMPDIR, "CA_Gnuplot_#{$$}_#{@temp_file_count}.dat")
494
- }
495
- yield(*tempfile)
496
- ensure
497
- tempfile.each do |file|
498
- if File.exist?(file)
499
- File.unlink(file)
500
- end
501
- end
502
- end
503
-
504
- def parse_args (argv, &block)
505
- opt = @defaults.clone
506
- if argv.size >= 1 and argv.last.is_a?(Hash)
507
- opt.update(argv.pop)
508
- elsif argv.size >= 1 and argv.last.is_a?(Option)
509
- opt = argv.pop
510
- end
511
- if block
512
- block.call(argv)
513
- end
514
- plots = argv.clone
515
- if opt.is_a? Option
516
- return plots, opt
517
- else
518
- return plots, Option.new(self, opt)
519
- end
520
- end
521
-
522
- def parse_data (list)
523
- list = list.clone
524
- conf = []
525
- while not list.empty? and
526
- ( list.last.is_a?(Integer) or
527
- list.last.is_a?(Symbol) or
528
- list.last.is_a?(String) or
529
- list.last.nil? )
530
- conf.unshift(list.pop)
531
- end
532
- if conf.last.is_a?(Integer)
533
- idx = conf.pop
534
- case idx
535
- when 1,2
536
- iy = idx
537
- axis = "x1y#{iy}"
538
- when 11,12,21,22
539
- ix = idx / 10
540
- iy = idx % 10
541
- axis = "x#{ix}y#{iy}"
542
- else
543
- raise "unknown axis specification"
544
- end
545
- end
546
- if conf.last.is_a?(Symbol)
547
- axis = conf.pop.to_s
548
- end
549
- using_ok = false
550
- using = nil
551
- if (conf.size == 2 or conf.size == 3 or conf.size == 4)
552
- if conf.first =~ /^every /
553
- dataspec = conf.shift
554
- elsif conf.first =~ /^using /
555
- using = conf.shift
556
- using_ok = true
557
- else
558
- dataspec = nil
559
- end
560
- else
561
- dataspec = nil
562
- end
563
- title, with = *conf
564
- if title =~ /\A\s*(col|column|columnhead|columnheader(\(.*?\)|))\s*\z/
565
- title = $1
566
- else
567
- title = %{"#{title}"}
568
- end
569
- return list, dataspec, using, title, with, axis
570
- end
571
-
572
- def histogram_tics (names)
573
- return names.to_a.map.with_index {|n,i| [i,n.to_s]}
574
- end
575
-
576
- public
577
-
578
- def plot_number
579
- return @multiplot_plot_number
580
- end
581
-
582
- def multiplot (option = {})
583
- @multiplot_mode = true
584
- @multiplot_option = option
585
- @multiplot_plot_number = 1
586
- @saved_init = @init
587
- options = ""
588
- if option[:layout]
589
- options << " layout " + option[:layout].join(",")
590
- if option[:columnsfirst]
591
- options << " columnsfirst "
592
- else
593
- options << " rowsfirst "
594
- end
595
- if option[:upwards]
596
- options << " upwards "
597
- else
598
- options << " downwards "
599
- end
600
- end
601
- if option[:scale]
602
- options << " scale " + option[:scale].join(",")
603
- end
604
- if option[:offset]
605
- options << " offset " + option[:offset].join(",")
606
- end
607
- if option[:title]
608
- options << " title '" + option[:title] + "'"
609
- end
610
- put( "set multiplot" + options )
611
- reset()
612
- yield
613
- ensure
614
- put( "unset multiplot" )
615
- @multiplot_option = nil
616
- @multiplot_mode = false
617
- @multiplot_plot_number = 0
618
- @init = @saved_init
619
- unless option[:nopause]
620
- pause
621
- end
622
- unless option[:noreset]
623
- reset
624
- end
625
- end
626
-
627
- def canvas (*argv, &block)
628
- plots, opt = parse_args(argv, &block)
629
- put %{
630
- unset xtics
631
- unset x2tics
632
- unset ytics
633
- unset y2tics
634
- unset xlabel
635
- unset ylabel
636
- unset x2label
637
- unset y2label
638
- unset key
639
- }
640
- opt.set(:margin, :title, :bgcolor,
641
- :xaxis, :yaxis, :x2axis, :y2axis,
642
- :border, :parametric,
643
- :options)
644
- put %{
645
- plot "-" with dots
646
- -1e30,-1e30
647
- e
648
- }
649
- if @multiplot_mode
650
- @multiplot_plot_number += 1
651
- end
652
- pause() unless opt[:nopause]
653
- reset() unless opt[:noreset]
654
- end
655
-
656
- def scanvas (*argv, &block)
657
- plots, opt = parse_args(argv, &block)
658
- put %{
659
- unset xtics
660
- unset x2tics
661
- unset ytics
662
- unset y2tics
663
- unset ztics
664
- unset xlabel
665
- unset ylabel
666
- unset zlabel
667
- unset x2label
668
- unset y2label
669
- unset key
670
- }
671
- opt.set(:margin, :title, :bgcolor,
672
- :xaxis, :yaxis, :zaxis,
673
- :border, :parametric,
674
- :options)
675
- put %{
676
- splot "-" with dots
677
- -1e30,-1e30,-1e30
678
- e
679
- }
680
- if @multiplot_mode
681
- @multiplot_plot_number += 1
682
- end
683
- pause() unless opt[:nopause]
684
- reset() unless opt[:noreset]
685
- end
686
-
687
- #
688
- # with csv file
689
- # ["foo.csv","1:2","title","with","y2"]
690
- #
691
- def blank (*argv, &block)
692
- plots, opt = parse_args(argv, &block)
693
- put %{
694
- unset xtics
695
- unset ytics
696
- unset x2tics
697
- unset y2tics
698
- unset xlabel
699
- unset ylabel
700
- unset x2label
701
- unset y2label
702
- unset border
703
- unset key
704
- unset grid
705
- }
706
- opt.set(:margin, :title, :bgcolor,
707
- :parametric,
708
- :options)
709
- put %{
710
- plot [0:1] [0:1] "-" with dots
711
- -1,-1
712
- e
713
- }
714
- if @multiplot_mode
715
- @multiplot_plot_number += 1
716
- end
717
- pause() unless opt[:nopause]
718
- reset() unless opt[:noreset]
719
- end
720
-
721
- #
722
- # with csv file
723
- # ["foo.csv","1:2","title","with","axes"]
724
- #
725
- # with csv string
726
- # ["1,2\n2,3\n4,5","1:2","title","with","axes"]
727
- #
728
- def plot (*argv, &block)
729
- @init.call if @init
730
- plots, opt = parse_args(argv, &block)
731
- @last = plots + [opt]
732
- with_tempfile(plots.size) { |*tempfile|
733
- plot_list = []
734
- plots.each_with_index do |arg, i|
735
- arg = arg.clone
736
- local_ranges = []
737
- loop do
738
- case arg.first
739
- when Range
740
- rng = arg.shift
741
- local_ranges << "[" + [rng.begin,rng.end].join(":") + "] "
742
- when Hash
743
- var,rng = arg.shift.first
744
- case var
745
- when :x
746
- local_ranges[0] = "[" + [rng.begin,rng.end].join(":") + "] "
747
- when :y
748
- local_ranges[1] = "[" + [rng.begin,rng.end].join(":") + "] "
749
- when :z
750
- local_ranges[2] = "[" + [rng.begin,rng.end].join(":") + "] "
751
- else
752
- local_ranges << "[#{var}=" + [rng.begin,rng.end].join(":") + "] "
753
- end
754
- else
755
- break
756
- end
757
- end
758
- if i == 0 and not local_ranges.empty?
759
- local_ranges.unshift "sample"
760
- end
761
- local_ranges = local_ranges.map{|v| v.nil? ? "[:]" : v }
762
- if arg.first.is_a?(Symbol) and arg.first == :newhistogram
763
- arg.shift
764
- arg, dataspec, using, title, with, axis = *parse_data(arg)
765
- plot_cmd = [
766
- "newhistogram",
767
- using ? using : "",
768
- title ? title : "",
769
- with ? with : "",
770
- ]
771
- elsif arg.first.is_a?(DataBlock)
772
- datablock = arg.shift
773
- if datablock.is_csv?
774
- put("set datafile separator ','")
775
- end
776
- arg, dataspec, using, title, with, axis = *parse_data(arg)
777
- plot_cmd = local_ranges + [
778
- datablock.name,
779
- dataspec ? dataspec : "",
780
- @gnuplot_version >= 4.4 ? "volatile" : "",
781
- opt[:using] ? "using " + opt[:using] :
782
- using ? using : "",
783
- axis ? "axes #{axis}" : "",
784
- with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
785
- title ? "title #{title}" : ""
786
- ]
787
- elsif arg.first.is_a?(String)
788
- file = arg.shift
789
- if file =~ /\.(png|jpg)\z/
790
- arg, dataspec, using, title, with, axis = *parse_data(arg)
791
- plot_cmd = local_ranges + [
792
- "'#{file}'",
793
- dataspec ? dataspec : "",
794
- "binary filetype=auto",
795
- @gnuplot_version >= 4.4 ? "volatile" : "",
796
- opt[:using] ? "using " + opt[:using] :
797
- using ? using : "",
798
- axis ? "axes #{axis}" : "",
799
- with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
800
- title ? "title #{title}" : ""
801
- ]
802
- else
803
- if file == ""
804
- elsif file =~ /,/ or file =~ /[\n\r]/
805
- if file =~ /,/
806
- put("set datafile separator ','")
807
- end
808
- file = file.gsub(/UNDEF/, "NaN")
809
- open(tempfile[i], "w") { |io| io.write file }
810
- file = tempfile[i]
811
- else
812
- unless File.exist?(file)
813
- raise "can't open file #{file} for plot2d"
814
- end
815
- end
816
- arg, dataspec, using, title, with, axis = *parse_data(arg)
817
- plot_cmd = local_ranges + [
818
- "'#{file}'",
819
- dataspec ? dataspec : "",
820
- @gnuplot_version >= 4.4 ? "volatile" : "",
821
- opt[:using] ? "using " + opt[:using] :
822
- using ? using : "",
823
- axis ? "axes #{axis}" : "",
824
- with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
825
- title ? "title #{title}" : ""
826
- ]
827
- end
828
- elsif arg.first.is_a?(Array)
829
- funcs, dataspec, using, title, with, axis = *parse_data(arg)
830
- plot_cmd = local_ranges + [
831
- funcs.join(","),
832
- dataspec ? dataspec : "",
833
- opt[:using] ? "using " + opt[:using] :
834
- using ? using : "",
835
- axis ? "axes #{axis}" : "",
836
- with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
837
- title ? "title #{title}" : ""
838
- ]
839
- else
840
- arg, dataspec, using, title, with, axis = *parse_data(arg)
841
- arg = arg.map{|x| CArray.wrap_readonly(x, CA_DOUBLE) }
842
- if with.to_s =~ /rgbimage/ or opt[:with].to_s =~ /rgbimage/
843
- if arg[2] and arg[2].rank >= 2 and
844
- ( arg[2].size != arg[0].size or arg[2].size != arg[1].size )
845
- xlen = arg[0].size
846
- ylen = arg[1].size
847
- arg[0] = arg[0][ylen,:%]
848
- arg[1] = arg[1][:%,xlen]
849
- if arg[2].rank == 3
850
- arg2 = arg[2]
851
- arg[2] = arg2[nil,nil,0]
852
- arg[3] = arg2[nil,nil,1]
853
- arg[4] = arg2[nil,nil,2]
854
- end
855
- end
856
- is_image = true
857
- is_rgb = true
858
- elsif with.to_s =~ /image/ or opt[:with].to_s =~ /image/
859
- if arg[2] and arg[2].rank == 2 and
860
- ( arg[2].size != arg[0].size or arg[2].size != arg[1].size )
861
- xlen = arg[0].size
862
- ylen = arg[1].size
863
- arg[0] = arg[0][ylen,:%]
864
- arg[1] = arg[1][:%,xlen]
865
- end
866
- is_image = true
867
- is_rgb = false
868
- else
869
- arg = arg.map{|x| x.rank > 1 ? x[nil] : x }
870
- is_image = false
871
- end
872
- out = CArray.merge(CA_DOUBLE, arg, -1)
873
- if is_image
874
- if is_rgb
875
- datalen = out.dim2
876
- if arg.size == 1
877
- datalen = 1
878
- array = "(" + [out.dim1,out.dim0].join(',') + ")"
879
- record = nil
880
- else
881
- datalen = 5
882
- array = nil
883
- record = "(" + [out.dim1,out.dim0].join(',') + ")"
884
- end
885
- else
886
- if arg.size == 1
887
- datalen = 1
888
- array = "(" + [out.dim1,out.dim0].join(',') + ")"
889
- record = nil
890
- else
891
- datalen = 3
892
- array = nil
893
- record = out.dim1*out.dim0
894
- end
895
- end
896
- else
897
- datalen = arg.size
898
- record = out.dim0
899
- array = nil
900
- end
901
- open(tempfile[i], "w") { |io|
902
- out.unmask_copy(0.0/0.0).dump_binary(io)
903
- }
904
- plot_cmd = local_ranges + [
905
- "'#{tempfile[i]}'",
906
- "binary",
907
- record ? "record=#{record}" : "",
908
- array ? "array=#{array}" : "",
909
- "format='#{'%double'*datalen}'",
910
- dataspec ? dataspec : "",
911
- @gnuplot_version >= 4.4 ? "volatile" : "",
912
- opt[:using] ? "using " + opt[:using] :
913
- using ? using :
914
- "using " + "#{(1..datalen).map{|x|'%i' % x}.join(':')}",
915
- axis ? "axes #{axis}" : "",
916
- with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
917
- title ? "title #{title}" : ""
918
- ]
919
- end
920
- plot_list.push(plot_cmd.join(" "))
921
- end
922
- opt.set(:margin, :title, :key, :bgcolor, :palette,
923
- :timefmt, :xaxis, :x2axis, :yaxis, :y2axis,
924
- :cbaxis, :grid, :border, :parametric,
925
- :options)
926
- put("plot " + plot_list.join(","))
927
- if @multiplot_mode
928
- @multiplot_plot_number += 1
929
- end
930
- pause() unless opt[:nopause]
931
- reset() unless opt[:noreset]
932
- }
933
- end
934
-
935
- alias scatter plot
936
- alias plot2d plot
937
-
938
- def splot (*argv, &block)
939
- @init.call if @init
940
- plots, opt = parse_args(argv, &block)
941
- @last = plots + [opt]
942
- with_tempfile(plots.size) { |*tempfile|
943
- plot_list = []
944
- plots.each_with_index do |arg, i|
945
- arg = arg.clone
946
- local_ranges = []
947
- loop do
948
- case arg.first
949
- when Range
950
- rng = arg.shift
951
- local_ranges << "[" + [rng.begin,rng.end].join(":") + "] "
952
- when Hash
953
- var,rng = arg.shift.first
954
- case var
955
- when :x
956
- local_ranges[0] = "[" + [rng.begin,rng.end].join(":") + "] "
957
- when :y
958
- local_ranges[1] = "[" + [rng.begin,rng.end].join(":") + "] "
959
- when :z
960
- local_ranges[2] = "[" + [rng.begin,rng.end].join(":") + "] "
961
- else
962
- local_ranges << "[#{var}=" + [rng.begin,rng.end].join(":") + "] "
963
- end
964
- else
965
- break
966
- end
967
- end
968
- if i == 0 and not local_ranges.empty?
969
- local_ranges.unshift "sample"
970
- end
971
- local_ranges = local_ranges.map{|v| v.nil? ? "[:]" : v }
972
- if arg.first.is_a?(DataBlock)
973
- datablock = arg.shift
974
- if datablock.is_csv?
975
- put("set datafile separator ','")
976
- end
977
- arg, dataspec, using, title, with, axis = *parse_data(arg)
978
- plot_cmd = local_ranges + [
979
- datablock.name,
980
- dataspec ? dataspec : "",
981
- @gnuplot_version >= 4.4 ? "volatile" : "",
982
- opt[:using] ? "using " + opt[:using] :
983
- using ? using : "",
984
- axis ? "axes #{axis}" : "",
985
- with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
986
- title ? "title #{title}" : ""
987
- ]
988
- elsif arg.first.is_a?(String)
989
- file = arg.shift
990
- if file =~ /\.(png|jpg)\z/
991
- arg, dataspec, using, title, with, axis = *parse_data(arg)
992
- plot_cmd = [
993
- "'#{file}'",
994
- dataspec ? dataspec : "",
995
- "binary filetype=auto",
996
- @gnuplot_version >= 4.4 ? "volatile" : "",
997
- opt[:using] ? "using " + opt[:using] :
998
- using ? using : "",
999
- axis ? "axes #{axis}" : "",
1000
- with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
1001
- title ? "title #{title}" : ""
1002
- ]
1003
- else
1004
- if file == ""
1005
- elsif file =~ /,/ or file =~ /[\n\r]/
1006
- if file =~ /,/
1007
- put("set datafile separator ','")
1008
- end
1009
- file = file.gsub(/UNDEF/, "NaN")
1010
- open(tempfile[i], "w") { |io| io.write file }
1011
- file = tempfile[i]
1012
- else
1013
- unless File.exist?(file)
1014
- raise "can't open file #{file} for splot"
1015
- end
1016
- end
1017
- arg, dataspec, using, title, with, axis = *parse_data(arg)
1018
- plot_cmd = [
1019
- "'#{file}'",
1020
- dataspec ? dataspec : "",
1021
- @gnuplot_version >= 4.4 ? "volatile" : "",
1022
- opt[:using] ? "using " + opt[:using] :
1023
- using ? using : "",
1024
- axis ? "axes #{axis}" : "",
1025
- with ? "with #{with}"
1026
- : opt[:with] ? "with #{opt[:with]}" : "",
1027
- title ? "title #{title}" : ""
1028
- ]
1029
- end
1030
- elsif arg.first.is_a?(Array)
1031
- funcs, dataspec, using, title, with, axis = *parse_data(arg)
1032
- plot_cmd = [
1033
- funcs.join(","),
1034
- dataspec ? dataspec : "",
1035
- opt[:using] ? "using " + opt[:using] :
1036
- using ? using : "",
1037
- axis ? "axes #{axis}" : "",
1038
- with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
1039
- title ? "title #{title}" : ""
1040
- ]
1041
- else
1042
- arg, dataspec, using, title, with, axis = *parse_data(arg)
1043
- arg = arg.map{|x| CArray.wrap_readonly(x, CA_DOUBLE) }
1044
- if arg[2] and arg[2].rank == 2 and
1045
- ( arg[2].size != arg[0].size or arg[2].size != arg[1].size )
1046
- xlen = arg[0].size
1047
- ylen = arg[1].size
1048
- arg[0] = arg[0][ylen,:%]
1049
- arg[1] = arg[1][:%,xlen]
1050
- is_image = true
1051
- elsif arg[0] and arg[0].rank == 2
1052
- is_image = true
1053
- elsif arg[0] and arg[0].rank == 3
1054
- is_image = true
1055
- else
1056
- is_image = false
1057
- end
1058
- out = CArray.merge(CA_DOUBLE, arg, -1)
1059
- if is_image
1060
- datalen = out.dim2
1061
- record = "(" + [out.dim1,out.dim0].join(",") + ")"
1062
- else
1063
- datalen = arg.size
1064
- record = out.dim0
1065
- end
1066
- open(tempfile[i], "w") { |io|
1067
- out.unmask_copy(0.0/0.0).dump_binary(io)
1068
- }
1069
- plot_cmd = local_ranges + [
1070
- "'#{tempfile[i]}'",
1071
- "binary",
1072
- record ? "record=#{record}" : "",
1073
- "format='#{'%double'*datalen}'",
1074
- dataspec ? dataspec : "",
1075
- @gnuplot_version >= 4.4 ? "volatile" : "",
1076
- opt[:using] ? "using " + opt[:using] :
1077
- using ? using :
1078
- "using " + "#{(1..datalen).map{|x|'%i' % x}.join(':')}",
1079
- axis ? "axes #{axis}" : "",
1080
- with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
1081
- title ? "title #{title}" : ""
1082
- ]
1083
- end
1084
- plot_list.push(plot_cmd.join(" "))
1085
- end
1086
- opt.set(:margin, :title, :key, :bgcolor, :view, :palette,
1087
- :timefmt, :xaxis, :yaxis, :zaxis,
1088
- :cbaxis, :border, :parametric, :options)
1089
- put("splot " + plot_list.join(","))
1090
- if @multiplot_mode
1091
- @multiplot_plot_number += 1
1092
- end
1093
- pause() unless opt[:nopause]
1094
- reset() unless opt[:noreset]
1095
- }
1096
- end
1097
-
1098
- alias scatter3d splot
1099
- alias mesh3d splot
1100
- alias grid3d splot
1101
-
1102
- def image (*argv, &block)
1103
- raise "image() will be obsolete, use plot(..., :with=>'(rgb)image')"
1104
- end
1105
-
1106
- def imagemap (*argv, &block)
1107
- raise "imagemap() will be obsolete, use plot(..., :with=>'(rgb)image')"
1108
- end
1109
-
1110
- #
1111
- # fit(function, params, data, options)
1112
- #
1113
- #
1114
- # with csv file
1115
- # ["foo.csv","1:2","title","with","axes"]
1116
- #
1117
- # with csv string
1118
- # ["1,2\n2,3\n4,5","1:2","title","with","axes"]
1119
- #
1120
- def fit (expr, params, data, opt = {})
1121
- with_tempfile(2) { |tempfile, logfile|
1122
- if data.first.is_a?(DataBlock)
1123
- datablock = data.shift
1124
- if datablock.is_csv?
1125
- put("set datafile separator ','")
1126
- end
1127
- using = data.shift
1128
- fitdata = [
1129
- datablock.name,
1130
- using ? "using " + using :
1131
- opt[:using] ? "using " + opt[:using] : "",
1132
- ]
1133
- elsif data.first.is_a?(String)
1134
- file = data.shift
1135
- if file =~ /,/ or file =~ /[\n\r]/
1136
- if file =~ /,/
1137
- put("set datafile separator ','")
1138
- end
1139
- open(tempfile, "w") { |io| io.write file }
1140
- file = tempfile
1141
- else
1142
- unless File.exist?(file)
1143
- raise "can't open file #{file} for plot2d"
1144
- end
1145
- end
1146
- using = data.shift
1147
- fitdata = [
1148
- "'#{file}'",
1149
- using ? "using " + using :
1150
- opt[:using] ? "using " + opt[:using] : "",
1151
- ]
1152
- else
1153
- arg = data.map{|x| CArray.wrap_readonly(x, CA_DOUBLE) }
1154
- if arg[2] and arg[2].rank == 2 and
1155
- ( arg[2].size != arg[0].size or arg[2].size != arg[1].size )
1156
- xlen = arg[0].size
1157
- ylen = arg[1].size
1158
- arg[0] = arg[0][ylen,:%]
1159
- arg[1] = arg[1][:%,xlen]
1160
- record = arg[0].dim1
1161
- elsif arg[0] and arg[0].rank == 2
1162
- record = arg[0].dim1
1163
- else
1164
- record = arg[0].dim0
1165
- end
1166
- datalen = arg.size
1167
- out = CArray.merge(CA_DOUBLE, arg, -1)
1168
- open(tempfile, "w") { |io|
1169
- out.unmask_copy(0.0/0.0).dump_binary(io)
1170
- }
1171
- fitdata = [
1172
- "'#{tempfile}'",
1173
- "binary",
1174
- record ? "record=#{record}" : "",
1175
- "format='#{'%double'*datalen}'",
1176
- "using " + ( opt[:using] ||
1177
- "#{(1..datalen).map{|x|'($%i)' % x}.join(':')}" ),
1178
- ]
1179
- end
1180
- if opt[:ranges]
1181
- ranges = opt[:ranges]
1182
- else
1183
- ranges = ""
1184
- end
1185
- set("fit logfile '#{logfile}' errorvariables covariancevariables")
1186
- put("fit #{ranges} #{expr} #{fitdata.join(" ")} via " + params.map{|x| x.to_s}.join(","))
1187
- res = OpenStruct.new
1188
- res.expression = expr
1189
- res.parameters = params
1190
- result_params = put("print " + params.map{|x| x.to_s}.join(",")).split.map{|_x| _x.to_f}
1191
- result_err = put("print " + params.map{|x| x.to_s + "_err"}.join(",")).split.map{|_x| _x.to_f}
1192
- result_cov = put("print " + params.map{|x| params.map{|y| "FIT_COV_" + x.to_s + "_" + y.to_s }}.join(",")).split.map{|_x| _x.to_f}
1193
- params.each_with_index do |name, i|
1194
- res.send(name.to_s+"=", result_params[i])
1195
- res.send(name.to_s+"_err=", result_err[i])
1196
- end
1197
- i=0
1198
- params.each do |x|
1199
- params.each do |y|
1200
- res.send("cov_" + x.to_s + "_" + y.to_s + "=", result_cov[i])
1201
- end
1202
- i+=1
1203
- end
1204
- res.log = File.read(logfile)
1205
- result = put("print FIT_NDF, FIT_WSSR, FIT_STDFIT, FIT_P")
1206
- res.ndf, res.wssr, res.stdfit, res.fit_p = result.split.map{|_x| _x.to_f}
1207
-
1208
- return result_params, res
1209
- }
1210
- end
1211
-
1212
- #
1213
- # my_palette = [[0, '#ffffff'],
1214
- # [1, '#909090'],
1215
- # [5, '#000090'],
1216
- # [10, '#000fff'],
1217
- # [25, '#0090ff'],
1218
- # [50, '#0fffee'],
1219
- # [75, '#90ff70'],
1220
- # [100,'#ffee00'],
1221
- # [200,'#ff7000'],
1222
- # [300,'#ee0000'],
1223
- # [400,'#7f0000']]
1224
- # index = gp.set_palette_discrete(depth, my_palette)
1225
- def set_palette_discrete (data, my_palette, option = {})
1226
- default = { :model=>"RGB",
1227
- :continuous=>false,
1228
- :lower=>nil,
1229
- :upper=>nil,
1230
- :lower_label=>false,
1231
- :upper_label=>false }
1232
- option = default.update(option)
1233
- model, continuous, lower, lower_label, upper, upper_label =
1234
- option.values_at(:model, :continuous, :lower, :lower_label, :upper, :upper_label)
1235
- levels = my_palette.size
1236
- scale = my_palette.map{|r| r[0] }
1237
- scalec = scale.clone
1238
- color = my_palette.map{|r| r[1] }
1239
- out = []
1240
- cbmin = 0
1241
- cbmax = levels - 1
1242
- maxcolors = levels-1
1243
- if continuous
1244
- if lower
1245
- out << [-1, %{'#{lower}'}]
1246
- cbmin = -1
1247
- maxcolors += 1
1248
- end
1249
- (levels).times do |i|
1250
- level = i
1251
- out << [level, %{'#{color[i]}'}]
1252
- end
1253
- if upper
1254
- out << [levels, %{'#{upper}'}]
1255
- cbmax = levels
1256
- maxcolors += 1
1257
- end
1258
- else
1259
- if lower
1260
- out << [-1, %{'#{lower}'}]
1261
- out << [0, %{'#{lower}'}]
1262
- cbmin = -1
1263
- maxcolors += 1
1264
- end
1265
- (levels-1).times do |i|
1266
- level = i
1267
- level1 = i+1
1268
- out << [level, %{'#{color[i]}'}]
1269
- out << [level1, %{'#{color[i]}'}]
1270
- end
1271
- if upper
1272
- out << [levels-1, %{'#{upper}'}]
1273
- out << [levels, %{'#{upper}'}]
1274
- cbmax = levels
1275
- maxcolors += 1
1276
- end
1277
- end
1278
- put ["set palette model #{model} maxcolors #{maxcolors} defined (\\",
1279
- out.map{|list| " " + list.join(" ")}.join(",\\\n") + "\\",
1280
- ")"].join("\n")
1281
- out = []
1282
- if lower and lower_label
1283
- out << [%{''{/Symbol <}#{scale.first}'}, cbmin]
1284
- end
1285
- scale.each_with_index do |s, i|
1286
- out << [%{'#{s}'}, i]
1287
- end
1288
- if upper and upper_label
1289
- out << [%{'{/Symbol \\263}#{scale.last}'}, cbmax]
1290
- end
1291
- put %{ set cbtics (#{out.map {|d| d.join(" ")}.join(",")}) }
1292
- put %{ set cbrange [#{cbmin}:#{cbmax}] }
1293
- return CA_DOUBLE(scale).section(data)
1294
- end
1295
-
1296
- #
1297
- def set_xtics_monthly (start, last, format: nil, interval: nil, linewidth: 1, style: "lc rgb 'black' back", grid: false)
1298
- unless format
1299
- format = "%b"
1300
- end
1301
- unless interval
1302
- interval = 3
1303
- end
1304
- case start
1305
- when String
1306
- start = DateTime.parse(start)
1307
- end
1308
- case last
1309
- when String
1310
- last = DateTime.parse(last)
1311
- end
1312
- if interval < 0
1313
- start = DateTime.parse(start.strftime("%Y-%m-01")) + 0.5
1314
- last = (DateTime.parse(last.strftime("%Y-%m-01"))) + 0.5 >> 1
1315
- else
1316
- start = DateTime.parse(start.strftime("%Y-%m-01"))
1317
- last = (DateTime.parse(last.strftime("%Y-%m-01"))) >> 1
1318
- end
1319
- set %{ xrange [#{time(start)}:#{time(last)}] }
1320
- if linewidth > 0
1321
- set %{ xtics ("" 0) scale 0,2 mirror }
1322
- set %{ x2tics ("" 0) scale 0,1 mirror }
1323
- else
1324
- set %{ xtics ("" 0) scale 0,0 mirror }
1325
- set %{ x2tics ("" 0) scale 0,0 mirror }
1326
- end
1327
- d = start
1328
- while d <= last
1329
- set %{ xtics add ('' #{time(d)} 1) }
1330
- set %{ xtics add ('#{d.strftime(format)}' #{time(d+15)} 0) }
1331
- case interval
1332
- when -2,2
1333
- set %{ x2tics add ('' #{time(d+15)} 1) }
1334
- when -3,3
1335
- set %{ x2tics add ('' #{time(d+10)} 1) }
1336
- set %{ x2tics add ('' #{time(d+20)} 1) }
1337
- when -6,6
1338
- set %{ x2tics add ('' #{time(d+5)} 1) }
1339
- set %{ x2tics add ('' #{time(d+10)} 1) }
1340
- set %{ x2tics add ('' #{time(d+15)} 1) }
1341
- set %{ x2tics add ('' #{time(d+20)} 1) }
1342
- set %{ x2tics add ('' #{time(d+25)} 1) }
1343
- else
1344
- end
1345
- d >>= 1
1346
- end
1347
- if grid and linewidth > 0
1348
- d = start >> 1
1349
- while d < last
1350
- set %{ arrow nohead from #{time(d)}, graph 0
1351
- rto graph 0, graph 1 #{style} }
1352
- d >>= 1
1353
- end
1354
- end
1355
- end
1356
-
1357
- class DataBlock
1358
-
1359
- @@datablock_count = 0
1360
-
1361
- def initialize (processor, *args)
1362
- put_ok = false
1363
- if args.size == 1 and args.first.is_a?(Symbol)
1364
- @name = "$" + args.first.to_s
1365
- @text = processor.put %{ print #{@name}}
1366
- elsif args.size == 1 and args.first.is_a?(String)
1367
- @@datablock_count += 1
1368
- @name = "$DBLK_#{@@datablock_count}"
1369
- @text = args.first.dup
1370
- put_ok = true
1371
- else
1372
- @@datablock_count += 1
1373
- @name = "$DBLK_#{@@datablock_count}"
1374
- @text = CArray.join(*args).to_csv
1375
- @text.gsub!(/UNDEF/,"NaN")
1376
- put_ok = true
1377
- end
1378
- @text.strip!
1379
- @text.chomp!
1380
- if put_ok
1381
- processor.put %{
1382
- #{@name} <<__EOD__
1383
- #{@text}
1384
- __EOD__
1385
- }
1386
- end
1387
- end
1388
-
1389
- def is_csv?
1390
- return (@text =~ /,/)
1391
- end
1392
-
1393
- def to_s
1394
- return @text.dup
1395
- end
1396
-
1397
- def to_ca
1398
- data = []
1399
- @text.each_line do |line|
1400
- case line
1401
- when /^#/
1402
- else
1403
- data << line.strip.split(/ +/)
1404
- end
1405
- end
1406
- return CA_OBJECT(data)
1407
- end
1408
-
1409
- attr_reader :name, :text
1410
-
1411
- end
1412
-
1413
- def datablock (*args)
1414
- return DataBlock.new(self, *args)
1415
- end
1416
-
1417
- class Option # :nodoc:
1418
-
1419
- def initialize (processor, option)
1420
- @processor = processor
1421
- @o = option
1422
- end
1423
-
1424
- def set (*names)
1425
- names.each do |name|
1426
- self.send("set_#{name}")
1427
- end
1428
- end
1429
-
1430
- def [] (name)
1431
- @o[name]
1432
- end
1433
-
1434
- def []= (name, value)
1435
- @o[name] = value
1436
- end
1437
-
1438
- def update (hash)
1439
- @o.update(hash)
1440
- end
1441
-
1442
- private
1443
-
1444
- def put (*lines)
1445
- return @processor.put(*lines)
1446
- end
1447
-
1448
- def evaluate (expr)
1449
- return @processor.evaluate(expr)
1450
- end
1451
-
1452
- def set_title
1453
- textcolor = @o[:fgcolor] ? "textcolor rgb \"#{@o[:fgcolor]}\"" : ""
1454
- if @o[:title]
1455
- put('set title "' + @o[:title] + '" ' + textcolor)
1456
- end
1457
- end
1458
-
1459
- def set_key
1460
- # ver = evaluate("GPVAL_VERSION")
1461
- # if ver.to_f <= 4.2
1462
- # tc = ""
1463
- # else
1464
- # tc = @o[:fgcolor] ? "tc rgb \"#{@o[:fgcolor]}\"" : ""
1465
- # end
1466
- # put("set key #{tc}")
1467
- end
1468
-
1469
- def set_bgcolor
1470
- if @o[:framecolor]
1471
- put "set object rect from screen 0, screen 0 " \
1472
- "to screen 1, screen 1 behind " \
1473
- "fc rgb '#{@o[:framecolor]}' " \
1474
- "fillstyle solid 1.0 noborder"
1475
- end
1476
- if @o[:shadowcolor]
1477
- put "set object rect from graph 0.01, graph -0.02 " \
1478
- "to graph 1.01, graph 0.98 behind " \
1479
- "fc rgb '#{@o[:shadowcolor]}' " \
1480
- "fillstyle solid 1.0 noborder"
1481
- end
1482
- if @o[:bgcolor]
1483
- put "set object rect from graph 0, graph 0 " \
1484
- "to graph 1, graph 1 behind " \
1485
- "fc rgb '#{@o[:bgcolor]}' " \
1486
- "fillstyle solid 1.0 noborder"
1487
- end
1488
- end
1489
-
1490
- def set_border
1491
- if @o[:noborder]
1492
- put("unset border")
1493
- end
1494
- if @o[:noaxis]
1495
- put("unset xtics")
1496
- put("unset ytics")
1497
- put("unset ztics")
1498
- put("unset xlabel")
1499
- put("unset ylabel")
1500
- put("unset zlabel")
1501
- return
1502
- end
1503
- if @o[:fgcolor]
1504
- put("set border linecolor rgb \"#{@o[:fgcolor]}\" ")
1505
- if @o[:zeroaxis]
1506
- put("set xzeroaxis linecolor rgb \"#{@o[:fgcolor]}\" ")
1507
- put("set yzeroaxis linecolor rgb \"#{@o[:fgcolor]}\" ")
1508
- end
1509
- else
1510
- if @o[:zeroaxis]
1511
- put("set xzeroaxis",
1512
- "set yzeroaxis")
1513
- end
1514
- end
1515
- end
1516
-
1517
- def set_axis(axis)
1518
- label, range, fmt, tics, mtics, ticsopts = *@o[axis]
1519
- logscale = @o["#{axis}log".intern]
1520
- timescale = @o["#{axis}time".intern]
1521
- reverse = @o["#{axis}reverse".intern]
1522
- textcolor = @o[:fgcolor] ? "textcolor rgb \"#{@o[:fgcolor]}\"" : ""
1523
- if label
1524
- put("set #{axis}label " + %{ "#{label} "} + textcolor)
1525
- else
1526
- put("unset #{axis}label")
1527
- end
1528
- if timescale
1529
- put("set #{axis}data time")
1530
- end
1531
- if range
1532
- case range
1533
- when Range
1534
- put("set #{axis}range [" + [range.begin,range.end].join(":") + "] " +
1535
- ( reverse ? "reverse " : "" ))
1536
- when Array
1537
- srange = range.join(":")
1538
- put("set #{axis}range [" + srange + "] " + ( reverse ? "reverse " : "" ))
1539
- else
1540
- raise "invalid range specification"
1541
- end
1542
- else
1543
- if reverse
1544
- put("set #{axis}range [*:*] reverse")
1545
- end
1546
- end
1547
- if tics
1548
- if tics.is_a?(Array)
1549
- ticslist = tics.collect do |v|
1550
- v = [v].flatten
1551
- case v.size
1552
- when 1
1553
- v.first.to_s
1554
- else
1555
- ['"'+v[1].to_s+'"', v[0], v[2]||0].join(" ")
1556
- end
1557
- end.join(",")
1558
- put("set #{axis}tics (#{ticslist}) #{textcolor} #{ticsopts}")
1559
- else
1560
- put("set #{axis}tics #{tics} #{textcolor} #{ticsopts}")
1561
- end
1562
- else
1563
- put("set #{axis}tics #{textcolor} #{ticsopts}")
1564
- end
1565
- if mtics
1566
- put("set m#{axis}tics #{mtics}")
1567
- end
1568
- if fmt
1569
- put(%{ set format #{axis} "#{fmt}"})
1570
- end
1571
- if logscale
1572
- put("set logscale #{axis}")
1573
- end
1574
- end
1575
-
1576
- def set_xaxis
1577
- set_axis(:x)
1578
- end
1579
-
1580
- def set_yaxis
1581
- set_axis(:y)
1582
- end
1583
-
1584
- def set_x2axis
1585
- if @o[:x2]
1586
- set_axis(:x2)
1587
- end
1588
- end
1589
-
1590
- def set_y2axis
1591
- if @o[:y2]
1592
- set_axis(:y2)
1593
- end
1594
- end
1595
-
1596
- def set_zaxis
1597
- set_axis(:z)
1598
- end
1599
-
1600
- def set_cbaxis
1601
- set_axis(:cb)
1602
- end
1603
-
1604
- def set_grid
1605
- if @o[:grid]
1606
- linecolor = @o[:fgcolor] ? "linecolor rgb \"#{@o[:fgcolor]}\"" : ""
1607
- case @o[:grid]
1608
- when Array
1609
- tics = @o[:grid].map{|a| "#{a}tics" }.join(" ")
1610
- put("set grid #{tics} back linetype 0 #{linecolor}")
1611
- else
1612
- put("set grid xtics ytics y2tics back linetype 0 #{linecolor}")
1613
- end
1614
- end
1615
- end
1616
-
1617
- def set_options
1618
- if @o[:ratio]
1619
- put("set size ratio #{@o[:ratio]}")
1620
- # put("set view equal xy")
1621
- end
1622
- end
1623
-
1624
- def set_timefmt
1625
- if @o[:timefmt]
1626
- put("set timefmt \"#{@o[:timefmt]}\"")
1627
- end
1628
- end
1629
-
1630
- def set_view
1631
- if @o[:view]
1632
- put("set view #{[@o[:view]].flatten.join(",")}")
1633
- end
1634
- end
1635
-
1636
- def set_parametric
1637
- if @o[:parametric]
1638
- put("set parametric")
1639
- end
1640
- end
1641
-
1642
- def set_margin
1643
- if @o[:floating] or
1644
- ( @processor.multiplot_mode and
1645
- ( @processor.multiplot_option[:layout] or
1646
- @processor.multiplot_option[:floating] ) )
1647
- if @o[:nomargin]
1648
- put("set lmargin 0",
1649
- "set rmargin 0",
1650
- "set tmargin 0",
1651
- "set bmargin 0")
1652
- end
1653
- else
1654
- put("set size 0.7, 0.7",
1655
- "set origin 0.15, 0.15",
1656
- "set lmargin 0",
1657
- "set rmargin 0",
1658
- "set tmargin 0",
1659
- "set bmargin 0")
1660
- end
1661
- end
1662
-
1663
- def set_palette (*argv)
1664
- case @o[:palette]
1665
- when Array
1666
- list = @o[:palette].clone
1667
- kind = list.shift
1668
- Palette.set(@processor, kind.intern, *list)
1669
- else
1670
- Palette.set(@processor, @o[:palette])
1671
- end
1672
- end
1673
-
1674
- end
1675
-
1676
- def palette (kind, *argv)
1677
- return Palette.set(self, kind, *argv)
1678
- end
1679
-
1680
- module Palette
1681
-
1682
- def self.quote (text)
1683
- case text
1684
- when Symbol
1685
- text.to_s
1686
- when /^\{\{(.*)\}\}$/
1687
- $1
1688
- else
1689
- text = text.clone
1690
- if text[0, 1] == "\\"
1691
- text[1..-1]
1692
- else
1693
- text.gsub!(/\n/, '\\n')
1694
- text.gsub!(/\t/, '\\t')
1695
- text.gsub!(/"/, '\\\\"')
1696
- '"' + text + '"'
1697
- end
1698
- end
1699
- end
1700
-
1701
- def self.set (gp, kind, *argv)
1702
- if argv.last.is_a?(Hash)
1703
- opt = argv.pop
1704
- else
1705
- opt = {}
1706
- end
1707
- if opt[:model]
1708
- gp.set %{ palette model #{opt[:model]} }
1709
- end
1710
- if opt[:maxcolors]
1711
- gp.set %{ palette maxcolors #{opt[:maxcolors]} }
1712
- end
1713
- case kind
1714
- when :defined
1715
- self.set_palette_array(gp, argv)
1716
- when :random
1717
- n = argv.first || 10
1718
- list = []
1719
- n.times do |i|
1720
- value = rand(256)*0x10000 + rand(256)*0x100 + rand(256)
1721
- list << [i, "#%6x" % value]
1722
- end
1723
- self.set_palette_array(gp, list)
1724
- when :rgbformulae
1725
- set_palette_formula(gp, *argv[0,3])
1726
- when :file
1727
- set_palette_file(gp, argv.first)
1728
- when :gmt
1729
- set_palette_gmt(gp, argv.first, opt)
1730
- when :cpt_city
1731
- set_palette_cpt_city(gp, argv.first, opt)
1732
- when Symbol
1733
- set_palette_predefined(gp, kind)
1734
- when String
1735
- set_palette_string(gp, kind)
1736
- when CArray
1737
- set_palette_carray(gp, kind)
1738
- when Array
1739
- self.set_palette_array(gp, kind)
1740
- when ColorPalette
1741
- set_palette_color_palette(gp, kind)
1742
- end
1743
- end
1744
-
1745
- def self.set_palette_formula (gp, *argv)
1746
- gp.set 'palette rgbformulae ' + argv.join(', ')
1747
- end
1748
-
1749
- def self.set_palette_file (gp, *argv)
1750
- gp.set 'palette file ' + quote(argv[0]) + " " + argv[1].to_s
1751
- end
1752
-
1753
- def self.set_palette_string (gp, string)
1754
- gp.set "palette " + string
1755
- end
1756
-
1757
- def self.set_palette_array (gp, array)
1758
- gp.set "palette " +
1759
- 'defined (' + array.map { |x|
1760
- case x[1]
1761
- when String
1762
- [x[0], quote(x[1])].join(' ')
1763
- else
1764
- x.join(' ')
1765
- end
1766
- }.join(', ') + ')'
1767
- end
1768
-
1769
- def self.set_palette_carray (gp, ca)
1770
- gp.instance_exec {
1771
- with_tempfile(1) { |tmpfile|
1772
- open(tmpfile, "w") {|io| ca.dump_binary(io)}
1773
- if ca.rank == 1 or ( ca.rank == 2 and ca.dim1 == 1)
1774
- set("palette file '#{tmpfile}' binary record=#{ca.dim0} using 1:1:1 model #{model}")
1775
- elsif ca.rank == 2 and ca.dim1 == 3
1776
- set("palette file '#{tmpfile}' binary record=#{ca.dim0} using 1:2:3 model #{model}")
1777
- else
1778
- raise "invalid palette specification"
1779
- end
1780
- }
1781
- }
1782
- end
1783
-
1784
- def self.set_palette_color_palette (gp, pal)
1785
- gp.put(pal.to_gnuplot)
1786
- end
1787
-
1788
- def self.set_palette_gmt (gp, name, opt)
1789
- cpt = ColorPalette::CPT(name, :continuous=>opt[:continuous])
1790
- if opt[:use_scale]
1791
- min, max = cpt.min, cpt.max
1792
- gp.set %{ cbrange [#{min}:#{max}] }
1793
- end
1794
- gp.put(cpt.to_gnuplot)
1795
- end
1796
-
1797
- def self.set_palette_cpt_city (gp, name, opt)
1798
- file = File.expand_path(File.join(ENV["CPTCITY"],name) + ".cpt")
1799
- cpt = ColorPalette::CPT(file, :continuous=>opt[:continuous])
1800
- if opt[:use_scale]
1801
- min, max = cpt.min, cpt.max
1802
- gp.set %{ cbrange [#{min}:#{max}] }
1803
- end
1804
- gp.put(cpt.to_gnuplot)
1805
- end
1806
-
1807
- def self.set_palette_predefined (gp, name)
1808
- case name.to_s
1809
- when "gray"
1810
- gp.set %{ palette defined (0 "#FFFFFF", \
1811
- 1 "#000000") }
1812
- when "gray_inv"
1813
- gp.set %{ palette defined (0 "#000000", \
1814
- 1 "#FFFFFF") }
1815
- when "rainbow"
1816
- gp.set %{ palette rgbformulae 22,13,-31 }
1817
- when "polar"
1818
- gp.set %{ palette defined (-1 "blue", \
1819
- 0 "white", \
1820
- 1 "red") }
1821
- when "jet"
1822
- gp.set %{ palette defined (0 "#00007F", \
1823
- 0.125 "#0000FF", \
1824
- 0.375 "#FFFFFF", \
1825
- 0.625 "#FFFF00", \
1826
- 0.875 "#FF0000", \
1827
- 1 "#7F0000") }
1828
- when "split"
1829
- gp.set %{ palette defined (-1.0 "#7F7FFF", \
1830
- -0.5 "#000080", \
1831
- 0.0 "#000000", \
1832
- 0.5 "#800000", \
1833
- 1.0 "#FF7F7F" ) }
1834
- when "green_metal"
1835
- gp.set %{ palette defined ( 0.0 "#000000", \
1836
- 0.5263 "#8D8D6C", \
1837
- 0.6842 "#92BDBE", \
1838
- 1.0 "#FFFFFF" )}
1839
- when "matlab"
1840
- gp.set %{ palette defined ( 0 '#000090', \
1841
- 1 '#000fff', \
1842
- 2 '#0090ff', \
1843
- 3 '#0fffee', \
1844
- 4 '#90ff70', \
1845
- 5 '#ffee00', \
1846
- 6 '#ff7000', \
1847
- 7 '#ee0000', \
1848
- 8 '#7f0000')}
1849
- when "matlab50"
1850
- gp.set %{ palette defined ( 0 '#00009080', \
1851
- 1 '#000fff80', \
1852
- 2 '#0090ff80', \
1853
- 3 '#0fffee80', \
1854
- 4 '#90ff7080', \
1855
- 5 '#ffee0080', \
1856
- 6 '#ff700080', \
1857
- 7 '#ee000080', \
1858
- 8 '#7f000080')}
1859
- when "matlabw"
1860
- gp.set %{ palette defined ( 0 'white',
1861
- 0.01 '#000090', \
1862
- 1 '#000fff', \
1863
- 2 '#0090ff', \
1864
- 3 '#0fffee', \
1865
- 4 '#90ff70', \
1866
- 5 '#ffee00', \
1867
- 6 '#ff7000', \
1868
- 7 '#ee0000', \
1869
- 8 '#7f0000')}
1870
- else
1871
- raise "Unknown palette name"
1872
- end
1873
- end
1874
-
1875
-
1876
- end
1877
-
1878
- class ColorPalette # :nodoc:
1879
-
1880
- def initialize (model, levels, color, scale = nil, continuous = false)
1881
- @model = model
1882
- @levels = levels
1883
- @color = color
1884
- @scale = scale || CArray.int(levels).seq!
1885
- @continuous = continuous
1886
- end
1887
-
1888
- attr_reader :scale, :colors
1889
-
1890
- def min
1891
- return @scale.min
1892
- end
1893
-
1894
- def max
1895
- return @scale.max
1896
- end
1897
-
1898
- def range
1899
- return @scale.min..@scale.max
1900
- end
1901
-
1902
- def to_gnuplot
1903
- out = []
1904
- maxcolors = 1024
1905
- if @continuous
1906
- (@levels).times do |i|
1907
- level = @scale[i]
1908
- out.push([level, *@color[i,nil].to_a])
1909
- end
1910
- else
1911
- (@levels-1).times do |i|
1912
- level = @scale[i]
1913
- level1 = @scale[i+1]
1914
- out.push([level, *@color[i,nil].to_a])
1915
- out.push([level1, *@color[i,nil].to_a])
1916
- end
1917
- maxcolors = @levels-1
1918
- end
1919
- return ["set palette model #{@model} maxcolors #{maxcolors} defined (\\",
1920
- out.map{|list| " " + list.join(" ")}.join(",\\\n") + "\\",
1921
- ")"].join("\n")
1922
- end
1923
-
1924
- end
1925
-
1926
- class ColorPalette
1927
-
1928
- def self.CPT (file, opt = nil)
1929
- options = {:continuous => false}.update(opt)
1930
- continuous = options[:continuous]
1931
- if File.exist?(file)
1932
- text = File.read(file)
1933
- else
1934
- if continuous
1935
- text = IO.popen("makecpt -C#{file} -Z", "r") { |io| io.read }
1936
- else
1937
- text = IO.popen("makecpt -C#{file}", "r") { |io| io.read }
1938
- end
1939
- if text =~ /\A\s*\Z/
1940
- raise "failed to makecpt #{file}"
1941
- end
1942
- end
1943
-
1944
- lines = text.split("\n").map{|line| line.strip }
1945
-
1946
- model = "HSV"
1947
- entries = []
1948
- lines.each do |line|
1949
- case line
1950
- when /\A\#\s*COLOR_MODEL\s*=\s*(.+)\s*\Z/
1951
- model = $1.upcase
1952
- when /\A\Z/, /\A#/, /\A([FBN])\s*(.*)\Z/
1953
- next
1954
- else
1955
- list = line.split(/\s+/)
1956
- list[1] = list[1].split(/\-/)
1957
- list[3] = list[3].split(/\-/)
1958
- list = list.flatten.map{|x| x.to_f}
1959
- entries.push(list)
1960
- end
1961
- end
1962
-
1963
- levels = entries.size * 2
1964
- color = CArray.float(levels, 3)
1965
- scale = CArray.float(levels)
1966
- level = 0
1967
- entries.each do |entry|
1968
- scale[level] = entry[0]
1969
- color[level, nil] = entry[1, 3]
1970
- level += 1
1971
- scale[level] = entry[4]
1972
- color[level, nil] = entry[5, 3]
1973
- level += 1
1974
- end
1975
- if model =~ /HSV/
1976
- color[nil, 0] /= 360
1977
- else
1978
- color[] /= 255
1979
- end
1980
-
1981
- return ColorPalette.new(model, levels, color, scale, options[:contiuous])
1982
- end
1983
-
1984
- def self.GMT (file, continuous = true)
1985
- return CPT(file, :continuous=>continuous)
1986
- end
1987
- end
1988
-
1989
- end
1990
-
1991
- class ColorPalette < CA::Gnuplot::ColorPalette
1992
- end
1993
-
1994
- class CA::Gnuplot
1995
-
1996
- def pi2arc (th0, th1)
1997
- return format("%f:%f", -th1+90, -th0+90)
1998
- end
1999
-
2000
- def xtics_histogram (ticslabels)
2001
- max = ticslabels.size - 1
2002
- return -0.5..max+0.5,
2003
- (0..max).map{|k|[k,ticslabels[k]]} + (0..max-1).map{|k|[k+0.5,"",1]}
2004
- end
2005
-
2006
- def guide_with_x11 (*arg)
2007
- @pause_mouse_mode = arg
2008
- @pause_mouse_term = "x11"
2009
- __guide__
2010
- end
2011
-
2012
- def guide_with_wxt (*arg)
2013
- @pause_mouse_mode = arg
2014
- @pause_mouse_term = "wxt"
2015
- __guide__
2016
- end
2017
-
2018
- def __guide__
2019
- guides = []
2020
- @pause_mouse_mode.each do |mode|
2021
- guide = ""
2022
- if mode.to_s[-1,1] == "!"
2023
- confirm = true
2024
- mode = mode.to_s[0..-2].intern
2025
- else
2026
- confirm = false
2027
- end
2028
- loop do
2029
- begin
2030
- put %{
2031
- set term push
2032
- set term #{@pause_mouse_term}
2033
- replot
2034
- }
2035
- case mode
2036
- when :click
2037
- puts "Wait mouse: 1-mouse click required"
2038
- put "pause mouse"
2039
- mx = evaluate "MOUSE_X"
2040
- my = evaluate "MOUSE_Y"
2041
- when :point
2042
- puts "Draw point: 1-mouse click required"
2043
- put "pause mouse"
2044
- mx = evaluate "MOUSE_X"
2045
- my = evaluate "MOUSE_Y"
2046
- guide = %{set %{ label "" at #{mx},#{my} point }}
2047
- set %{ label "" at #{mx},#{my} point pt 7 ps 2 }
2048
- put %{ refresh }
2049
- when :label, :clabel, :llabel, :rlabel
2050
- puts "Draw label: 1-mouse click required"
2051
- put "pause mouse"
2052
- mx = evaluate "MOUSE_X"
2053
- my = evaluate "MOUSE_Y"
2054
- print "label text: "
2055
- STDOUT.flush
2056
- text = STDIN.gets.chomp
2057
- case mode
2058
- when :label, :llabel
2059
- just = "left"
2060
- when :clabel
2061
- just = "center"
2062
- when :rlabel
2063
- just = "right"
2064
- end
2065
- guide = %{set %{ label #{text.dump} at #{"%.5g" % mx},#{"%.5g" %my} #{just} }}
2066
- set %{ label #{text.dump} at #{mx},#{my} #{just} }
2067
- put %{ refresh }
2068
- when :arrow
2069
- puts "Draw arrow: finish with right click"
2070
- guide = ""
2071
- pairs = []
2072
- i = 0
2073
- loop do
2074
- put "pause mouse"
2075
- mx = evaluate "MOUSE_X"
2076
- my = evaluate "MOUSE_Y"
2077
- mb = evaluate "MOUSE_BUTTON"
2078
- pairs << [mx, my]
2079
- if i >= 1
2080
- if i == 1
2081
- head = ""
2082
- else
2083
- head = "nohead"
2084
- end
2085
- mx1,my1 = pairs[i-1]
2086
- mx2,my2 = pairs[i]
2087
- guide << %{set %{ arrow from #{"%.5g" % mx2},#{"%.5g" % my2} to #{"%.5g" % mx1},#{"%.5g" % my1} #{head}} } << "\n"
2088
- set %{ arrow from #{"%.5g" % mx2},#{"%.5g" % my2} to #{"%.5g" % mx1},#{"%.5g" % my1} #{head}}
2089
- put %{ refresh }
2090
- end
2091
- if mb == "3"
2092
- break
2093
- end
2094
- i += 1
2095
- end
2096
- when :key
2097
- puts "Draw key: 1-mouse click required"
2098
- put "pause mouse"
2099
- mx = evaluate "MOUSE_X"
2100
- my = evaluate "MOUSE_Y"
2101
- guide = %{set %{ key at #{"%.5g" % mx},#{"%.5g" % my} }}
2102
- set %{ key at #{mx},#{my} }
2103
- put %{ refresh }
2104
- else
2105
- raise "invalid pause_mouse_mode #{@pause_mouse_mode}"
2106
- end
2107
- terminal %{ pop }
2108
- if @output
2109
- output @output
2110
- end
2111
- put %{ replot }
2112
- unset %{ output }
2113
- if confirm
2114
- print "ok? (Y/n) "
2115
- STDOUT.flush
2116
- begin
2117
- curstty = %x{stty -g}
2118
- system "stty raw -echo -icanon isig"
2119
- c = STDIN.getc;
2120
- ensure
2121
- system "stty #{curstty}"
2122
- end
2123
- puts
2124
- if c == ?N or c == ?n
2125
- raise
2126
- end
2127
- end
2128
- break
2129
- rescue
2130
- retry
2131
- end
2132
- end
2133
- guides << guide
2134
- end
2135
- @pause_mouse_mode = nil
2136
- puts guides.join("\n")
2137
- pause
2138
- end
2139
-
2140
-
2141
- end