carray 1.1.4 → 1.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/COPYING +56 -0
- data/GPL +340 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +33 -0
- data/LEGAL +50 -0
- data/NOTE +73 -0
- data/Rakefile +20 -0
- data/TODO +5 -0
- data/ca_iter_block.c +242 -0
- data/ca_iter_dimension.c +287 -0
- data/ca_iter_window.c +202 -0
- data/ca_obj_array.c +1189 -0
- data/ca_obj_bitarray.c +523 -0
- data/ca_obj_bitfield.c +636 -0
- data/ca_obj_block.c +885 -0
- data/ca_obj_fake.c +405 -0
- data/ca_obj_farray.c +482 -0
- data/ca_obj_field.c +625 -0
- data/ca_obj_grid.c +738 -0
- data/ca_obj_mapping.c +614 -0
- data/ca_obj_object.c +777 -0
- data/ca_obj_reduce.c +299 -0
- data/ca_obj_refer.c +627 -0
- data/ca_obj_repeat.c +640 -0
- data/ca_obj_select.c +558 -0
- data/ca_obj_shift.c +952 -0
- data/ca_obj_transpose.c +582 -0
- data/ca_obj_unbound_repeat.c +557 -0
- data/ca_obj_window.c +1023 -0
- data/carray.h +1381 -0
- data/carray_access.c +1798 -0
- data/carray_attribute.c +903 -0
- data/carray_call_cfunc.c +1107 -0
- data/carray_cast.c +1155 -0
- data/carray_cast_func.rb +498 -0
- data/carray_class.c +132 -0
- data/carray_conversion.c +518 -0
- data/carray_copy.c +453 -0
- data/carray_core.c +1307 -0
- data/carray_element.c +572 -0
- data/carray_generate.c +681 -0
- data/carray_iterator.c +630 -0
- data/carray_loop.c +462 -0
- data/carray_mask.c +1174 -0
- data/carray_math.rb +834 -0
- data/carray_numeric.c +257 -0
- data/carray_operator.c +582 -0
- data/carray_order.c +1040 -0
- data/carray_random.c +529 -0
- data/carray_sort_addr.c +261 -0
- data/carray_stat.c +2102 -0
- data/carray_stat_proc.rb +1990 -0
- data/carray_test.c +602 -0
- data/carray_undef.c +69 -0
- data/carray_utils.c +740 -0
- data/ext/calculus/carray_calculus.c +792 -0
- data/ext/calculus/carray_interp.c +355 -0
- data/ext/calculus/extconf.rb +12 -0
- data/ext/calculus/lib/autoload/autoload_math_calculus.rb +2 -0
- data/ext/calculus/lib/math/calculus.rb +119 -0
- data/ext/calculus/lib/math/interp/adapter_interp1d.rb +31 -0
- data/ext/dataframe/API.txt +11 -0
- data/ext/dataframe/extconf.rb +3 -0
- data/ext/dataframe/lib/carray/autoload/autoload_dataframe_dataframe.rb +14 -0
- data/ext/dataframe/lib/carray/dataframe/dataframe.rb +1104 -0
- data/ext/dataframe/sample/test_uniq_sort.rb +5 -0
- data/ext/fortio/extconf.rb +3 -0
- data/ext/fortio/lib/carray/autoload/autoload_fortran_format.rb +5 -0
- data/ext/fortio/lib/carray/io/fortran_format.rb +43 -0
- data/ext/fortio/lib/fortio.rb +3 -0
- data/ext/fortio/lib/fortio/fortran_format.rb +603 -0
- data/ext/fortio/lib/fortio/fortran_format.tab.rb +536 -0
- data/ext/fortio/lib/fortio/fortran_format.y +215 -0
- data/ext/fortio/lib/fortio/fortran_namelist.rb +151 -0
- data/ext/fortio/lib/fortio/fortran_namelist.tab.rb +470 -0
- data/ext/fortio/lib/fortio/fortran_namelist.y +213 -0
- data/ext/fortio/lib/fortio/fortran_sequential.rb +345 -0
- data/ext/fortio/ruby_fortio.c +182 -0
- data/ext/fortio/test/test_H.rb +5 -0
- data/ext/fortio/test/test_T.rb +7 -0
- data/ext/fortio/test/test_fortran_format.rb +86 -0
- data/ext/fortio/test/test_namelist.rb +25 -0
- data/ext/fortio/test/test_sequential.rb +13 -0
- data/ext/fortio/test/test_sequential2.rb +13 -0
- data/ext/fortio/work/test.rb +10 -0
- data/ext/fortio/work/test_e.rb +19 -0
- data/ext/fortio/work/test_ep.rb +10 -0
- data/ext/fortio/work/test_parse.rb +12 -0
- data/ext/imagemap/carray_imagemap.c +495 -0
- data/ext/imagemap/doc/call_graph.dot +28 -0
- data/ext/imagemap/draw.c +567 -0
- data/ext/imagemap/extconf.rb +13 -0
- data/ext/imagemap/lib/autoload/autoload_graphics_imagemap.rb +1 -0
- data/ext/imagemap/lib/graphics/imagemap.rb +273 -0
- data/ext/imagemap/lib/image_map.rb +4 -0
- data/ext/imagemap/test/swath_index.rb +83 -0
- data/ext/imagemap/test/swath_warp.rb +99 -0
- data/ext/imagemap/test/test.rb +23 -0
- data/ext/imagemap/test/test_image.rb +42 -0
- data/ext/imagemap/test/test_line.rb +14 -0
- data/ext/imagemap/test/test_rotate.rb +17 -0
- data/ext/imagemap/test/test_triangle.rb +20 -0
- data/ext/imagemap/test/test_warp.rb +26 -0
- data/ext/mathfunc/carray_mathfunc.c +321 -0
- data/ext/mathfunc/extconf.rb +18 -0
- data/ext/mathfunc/lib/autoload/autoload_math_mathfunc.rb +1 -0
- data/ext/mathfunc/lib/math/mathfunc.rb +15 -0
- data/ext/mathfunc/test/test_hypot.rb +5 -0
- data/ext/mathfunc/test/test_j0.rb +22 -0
- data/ext/mathfunc/test/test_jn.rb +8 -0
- data/ext/mathfunc/test/test_sph.rb +9 -0
- data/ext/narray/README +22 -0
- data/ext/narray/ca_wrap_narray.c +491 -0
- data/ext/narray/carray_narray.c +21 -0
- data/ext/narray/extconf.rb +57 -0
- data/ext/narray/lib/autoload/autoload_math_narray.rb +1 -0
- data/ext/narray/lib/autoload/autoload_math_narray_miss.rb +11 -0
- data/ext/narray/lib/math/narray.rb +17 -0
- data/ext/narray/lib/math/narray_miss.rb +45 -0
- data/extconf.rb +3 -25
- data/lib/carray.rb +28 -0
- data/lib/carray/autoload/autoload_base.rb +23 -0
- data/lib/carray/autoload/autoload_graphics_gnuplot.rb +2 -0
- data/lib/carray/autoload/autoload_io_csv.rb +14 -0
- data/lib/carray/autoload/autoload_io_excel.rb +5 -0
- data/lib/carray/autoload/autoload_io_imagemagick.rb +6 -0
- data/lib/carray/autoload/autoload_io_pg.rb +6 -0
- data/lib/carray/autoload/autoload_io_sqlite3.rb +12 -0
- data/lib/carray/autoload/autoload_io_table.rb +1 -0
- data/lib/carray/autoload/autoload_math_histogram.rb +5 -0
- data/lib/carray/autoload/autoload_math_interp.rb +4 -0
- data/lib/carray/autoload/autoload_math_recurrence.rb +6 -0
- data/lib/carray/autoload/autoload_object_iterator.rb +1 -0
- data/lib/carray/autoload/autoload_object_link.rb +1 -0
- data/lib/carray/autoload/autoload_object_pack.rb +2 -0
- data/lib/carray/base/autoload.rb +94 -0
- data/lib/carray/base/basic.rb +1051 -0
- data/lib/carray/base/inspect.rb +252 -0
- data/lib/carray/base/iterator.rb +367 -0
- data/lib/carray/base/math.rb +403 -0
- data/lib/carray/base/obsolete.rb +93 -0
- data/lib/carray/base/serialize.rb +260 -0
- data/lib/carray/base/struct.rb +634 -0
- data/lib/carray/graphics/gnuplot.rb +2116 -0
- data/lib/carray/info.rb +112 -0
- data/lib/carray/io/csv.rb +560 -0
- data/lib/carray/io/excel.rb +26 -0
- data/lib/carray/io/imagemagick.rb +231 -0
- data/lib/carray/io/pg.rb +101 -0
- data/lib/carray/io/sqlite3.rb +202 -0
- data/lib/carray/io/table.rb +77 -0
- data/lib/carray/math/histogram.rb +179 -0
- data/lib/carray/math/interp.rb +57 -0
- data/lib/carray/math/interp/adapter_gsl_spline.rb +47 -0
- data/lib/carray/math/recurrence.rb +95 -0
- data/lib/carray/mkmf.rb +145 -0
- data/lib/carray/object/ca_obj_iterator.rb +52 -0
- data/lib/carray/object/ca_obj_link.rb +52 -0
- data/lib/carray/object/ca_obj_pack.rb +101 -0
- data/mkmath.rb +731 -0
- data/mt19937ar.c +182 -0
- data/mt19937ar.h +86 -0
- data/rdoc_main.rb +27 -0
- data/rdoc_math.rb +5 -0
- data/rdoc_stat.rb +31 -0
- data/ruby_carray.c +242 -0
- data/ruby_ccomplex.c +497 -0
- data/ruby_float_func.c +83 -0
- data/spec/CABlockIterator/CABlockIterator_spec.rb +113 -0
- data/spec/CArray/bug/store_spec.rb +27 -0
- data/spec/CArray/index/repeat_spec.rb +10 -0
- data/spec/CArray/method/eq_spec.rb +80 -0
- data/spec/CArray/method/is_nan_spec.rb +12 -0
- data/spec/CArray/method/ne_spec.rb +18 -0
- data/spec/CArray/method/round_spec.rb +11 -0
- data/spec/CArray/object/_attribute_spec.rb +32 -0
- data/spec/CArray/object/s_new_spec.rb +31 -0
- data/spec/CArray/serialize/Serialization_spec.rb +89 -0
- data/spec/spec_all.rb +11 -0
- data/test/test_ALL.rb +50 -0
- data/test/test_CABitfield.rb +59 -0
- data/test/test_CABlock.rb +208 -0
- data/test/test_CAField.rb +40 -0
- data/test/test_CAGrid.rb +76 -0
- data/test/test_CAMapping.rb +106 -0
- data/test/test_CAMmap.rb +11 -0
- data/test/test_CARefer.rb +94 -0
- data/test/test_CARepeat.rb +66 -0
- data/test/test_CASelect.rb +23 -0
- data/test/test_CAShift.rb +17 -0
- data/test/test_CATranspose.rb +61 -0
- data/test/test_CAVirtual.rb +214 -0
- data/test/test_CAWindow.rb +55 -0
- data/test/test_CAWrap.rb +9 -0
- data/test/test_CArray.rb +228 -0
- data/test/test_CComplex.rb +83 -0
- data/test/test_CScalar.rb +91 -0
- data/test/test_attribute.rb +281 -0
- data/test/test_block_iterator.rb +17 -0
- data/test/test_boolean.rb +99 -0
- data/test/test_cast.rb +33 -0
- data/test/test_class.rb +85 -0
- data/test/test_complex.rb +43 -0
- data/test/test_composite.rb +125 -0
- data/test/test_convert.rb +79 -0
- data/test/test_copy.rb +141 -0
- data/test/test_creation.rb +85 -0
- data/test/test_element.rb +146 -0
- data/test/test_extream.rb +55 -0
- data/test/test_generate.rb +75 -0
- data/test/test_index.rb +71 -0
- data/test/test_mask.rb +578 -0
- data/test/test_math.rb +98 -0
- data/test/test_narray.rb +64 -0
- data/test/test_order.rb +147 -0
- data/test/test_random.rb +15 -0
- data/test/test_ref_store.rb +211 -0
- data/test/test_stat.rb +414 -0
- data/test/test_struct.rb +72 -0
- data/test/test_virtual.rb +49 -0
- data/utils/ca_ase.rb +21 -0
- data/utils/ca_methods.rb +15 -0
- data/utils/cast_checker.rb +30 -0
- data/utils/create_rdoc.sh +9 -0
- data/utils/diff_method.rb +52 -0
- data/utils/extract_rdoc.rb +27 -0
- data/utils/make_tgz.sh +3 -0
- data/utils/remove_resource_fork.sh +5 -0
- data/version.h +3 -3
- metadata +266 -1
@@ -0,0 +1,2116 @@
|
|
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, &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",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)
|
432
|
+
case data
|
433
|
+
when Numeric
|
434
|
+
data
|
435
|
+
when String
|
436
|
+
Time.parse(data) - @EP_T
|
437
|
+
when Time
|
438
|
+
data - @EP_T
|
439
|
+
when Date
|
440
|
+
(data - @EP_D)*86400
|
441
|
+
when DateTime
|
442
|
+
(data - @EP_DT)*86400
|
443
|
+
when CArray
|
444
|
+
return data.convert(CA_DOUBLE){|x|
|
445
|
+
case x
|
446
|
+
when Numeric
|
447
|
+
x
|
448
|
+
when Time
|
449
|
+
x - @EP_T
|
450
|
+
when Date
|
451
|
+
(x - @EP_D)*86400
|
452
|
+
when DateTime
|
453
|
+
(x - @EP_DT)*86400
|
454
|
+
when String
|
455
|
+
Time.parse(x) - @EP_T
|
456
|
+
end
|
457
|
+
}
|
458
|
+
when Range
|
459
|
+
time(data.first)..time(data.last)
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
def csv (*args)
|
464
|
+
list = []
|
465
|
+
args.each do |arg|
|
466
|
+
case arg
|
467
|
+
when Array
|
468
|
+
list.push(arg.to_ca)
|
469
|
+
else
|
470
|
+
list.push(arg)
|
471
|
+
end
|
472
|
+
end
|
473
|
+
return CArray.join(:object, list).to_csv
|
474
|
+
end
|
475
|
+
|
476
|
+
private
|
477
|
+
|
478
|
+
def with_tempfile (nfiles=1)
|
479
|
+
tempfile = Array.new(nfiles) {
|
480
|
+
@temp_file_count += 1
|
481
|
+
File.join(TMPDIR, "CA_Gnuplot_#{$$}_#{@temp_file_count}.dat")
|
482
|
+
}
|
483
|
+
yield(*tempfile)
|
484
|
+
ensure
|
485
|
+
tempfile.each do |file|
|
486
|
+
if File.exist?(file)
|
487
|
+
File.unlink(file)
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
def parse_args (argv, &block)
|
493
|
+
opt = @defaults.clone
|
494
|
+
if argv.size >= 1 and argv.last.is_a?(Hash)
|
495
|
+
opt.update(argv.pop)
|
496
|
+
elsif argv.size >= 1 and argv.last.is_a?(Option)
|
497
|
+
opt = argv.pop
|
498
|
+
end
|
499
|
+
if block
|
500
|
+
block.call(argv)
|
501
|
+
end
|
502
|
+
plots = argv.clone
|
503
|
+
if opt.is_a? Option
|
504
|
+
return plots, opt
|
505
|
+
else
|
506
|
+
return plots, Option.new(self, opt)
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
def parse_data (list)
|
511
|
+
list = list.clone
|
512
|
+
conf = []
|
513
|
+
while not list.empty? and
|
514
|
+
( list.last.is_a?(Fixnum) or
|
515
|
+
list.last.is_a?(Symbol) or
|
516
|
+
list.last.is_a?(String) or
|
517
|
+
list.last.nil? )
|
518
|
+
conf.unshift(list.pop)
|
519
|
+
end
|
520
|
+
if conf.last.is_a?(Fixnum)
|
521
|
+
idx = conf.pop
|
522
|
+
case idx
|
523
|
+
when 1,2
|
524
|
+
iy = idx
|
525
|
+
axis = "x1y#{iy}"
|
526
|
+
when 11,12,21,22
|
527
|
+
ix = idx / 10
|
528
|
+
iy = idx % 10
|
529
|
+
axis = "x#{ix}y#{iy}"
|
530
|
+
else
|
531
|
+
raise "unknown axis specification"
|
532
|
+
end
|
533
|
+
end
|
534
|
+
if conf.last.is_a?(Symbol)
|
535
|
+
axis = conf.pop.to_s
|
536
|
+
end
|
537
|
+
using_ok = false
|
538
|
+
using = nil
|
539
|
+
if (conf.size == 2 or conf.size == 3 or conf.size == 4)
|
540
|
+
if conf.first =~ /^every /
|
541
|
+
dataspec = conf.shift
|
542
|
+
elsif conf.first =~ /^using /
|
543
|
+
using = conf.shift
|
544
|
+
using_ok = true
|
545
|
+
else
|
546
|
+
dataspec = nil
|
547
|
+
end
|
548
|
+
else
|
549
|
+
dataspec = nil
|
550
|
+
end
|
551
|
+
title, with = *conf
|
552
|
+
if title =~ /\A\s*(col|column|columnhead|columnheader(\(.*?\)|))\s*\z/
|
553
|
+
title = $1
|
554
|
+
else
|
555
|
+
title = %{"#{title}"}
|
556
|
+
end
|
557
|
+
return list, dataspec, using, title, with, axis
|
558
|
+
end
|
559
|
+
|
560
|
+
def histogram_tics (names)
|
561
|
+
return names.to_a.map.with_index {|n,i| [i,n.to_s]}
|
562
|
+
end
|
563
|
+
|
564
|
+
public
|
565
|
+
|
566
|
+
def plot_number
|
567
|
+
return @multiplot_plot_number
|
568
|
+
end
|
569
|
+
|
570
|
+
def multiplot (option = {})
|
571
|
+
@multiplot_mode = true
|
572
|
+
@multiplot_option = option
|
573
|
+
@multiplot_plot_number = 1
|
574
|
+
@saved_init = @init
|
575
|
+
options = ""
|
576
|
+
if option[:layout]
|
577
|
+
options << " layout " + option[:layout].join(",")
|
578
|
+
if option[:columnsfirst]
|
579
|
+
options << " columnsfirst "
|
580
|
+
else
|
581
|
+
options << " rowsfirst "
|
582
|
+
end
|
583
|
+
if option[:upwards]
|
584
|
+
options << " upwards "
|
585
|
+
else
|
586
|
+
options << " downwards "
|
587
|
+
end
|
588
|
+
end
|
589
|
+
if option[:scale]
|
590
|
+
options << " scale " + option[:scale].join(",")
|
591
|
+
end
|
592
|
+
if option[:offset]
|
593
|
+
options << " offset " + option[:offset].join(",")
|
594
|
+
end
|
595
|
+
if option[:title]
|
596
|
+
options << " title '" + option[:title] + "'"
|
597
|
+
end
|
598
|
+
put( "set multiplot" + options )
|
599
|
+
reset()
|
600
|
+
yield
|
601
|
+
ensure
|
602
|
+
put( "unset multiplot" )
|
603
|
+
@multiplot_option = nil
|
604
|
+
@multiplot_mode = false
|
605
|
+
@multiplot_plot_number = 0
|
606
|
+
@init = @saved_init
|
607
|
+
unless option[:nopause]
|
608
|
+
pause
|
609
|
+
end
|
610
|
+
unless option[:noreset]
|
611
|
+
reset
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
def canvas (*argv, &block)
|
616
|
+
plots, opt = parse_args(argv, &block)
|
617
|
+
put %{
|
618
|
+
unset xtics
|
619
|
+
unset x2tics
|
620
|
+
unset ytics
|
621
|
+
unset y2tics
|
622
|
+
unset xlabel
|
623
|
+
unset ylabel
|
624
|
+
unset x2label
|
625
|
+
unset y2label
|
626
|
+
unset key
|
627
|
+
}
|
628
|
+
opt.set(:margin, :title, :bgcolor,
|
629
|
+
:xaxis, :yaxis, :x2axis, :y2axis,
|
630
|
+
:border, :parametric,
|
631
|
+
:options)
|
632
|
+
put %{
|
633
|
+
plot "-" with dots
|
634
|
+
-1e30,-1e30
|
635
|
+
e
|
636
|
+
}
|
637
|
+
if @multiplot_mode
|
638
|
+
@multiplot_plot_number += 1
|
639
|
+
end
|
640
|
+
pause() unless opt[:nopause]
|
641
|
+
reset() unless opt[:noreset]
|
642
|
+
end
|
643
|
+
|
644
|
+
def scanvas (*argv, &block)
|
645
|
+
plots, opt = parse_args(argv, &block)
|
646
|
+
put %{
|
647
|
+
unset xtics
|
648
|
+
unset x2tics
|
649
|
+
unset ytics
|
650
|
+
unset y2tics
|
651
|
+
unset ztics
|
652
|
+
unset xlabel
|
653
|
+
unset ylabel
|
654
|
+
unset zlabel
|
655
|
+
unset x2label
|
656
|
+
unset y2label
|
657
|
+
unset key
|
658
|
+
}
|
659
|
+
opt.set(:margin, :title, :bgcolor,
|
660
|
+
:xaxis, :yaxis, :zaxis,
|
661
|
+
:border, :parametric,
|
662
|
+
:options)
|
663
|
+
put %{
|
664
|
+
splot "-" with dots
|
665
|
+
-1e30,-1e30,-1e30
|
666
|
+
e
|
667
|
+
}
|
668
|
+
if @multiplot_mode
|
669
|
+
@multiplot_plot_number += 1
|
670
|
+
end
|
671
|
+
pause() unless opt[:nopause]
|
672
|
+
reset() unless opt[:noreset]
|
673
|
+
end
|
674
|
+
|
675
|
+
#
|
676
|
+
# with csv file
|
677
|
+
# ["foo.csv","1:2","title","with","y2"]
|
678
|
+
#
|
679
|
+
def blank (*argv, &block)
|
680
|
+
plots, opt = parse_args(argv, &block)
|
681
|
+
put %{
|
682
|
+
unset xtics
|
683
|
+
unset ytics
|
684
|
+
unset x2tics
|
685
|
+
unset y2tics
|
686
|
+
unset xlabel
|
687
|
+
unset ylabel
|
688
|
+
unset x2label
|
689
|
+
unset y2label
|
690
|
+
unset border
|
691
|
+
unset key
|
692
|
+
unset grid
|
693
|
+
}
|
694
|
+
opt.set(:margin, :title, :bgcolor,
|
695
|
+
:parametric,
|
696
|
+
:options)
|
697
|
+
put %{
|
698
|
+
plot [0:1] [0:1] "-" with dots
|
699
|
+
-1,-1
|
700
|
+
e
|
701
|
+
}
|
702
|
+
if @multiplot_mode
|
703
|
+
@multiplot_plot_number += 1
|
704
|
+
end
|
705
|
+
pause() unless opt[:nopause]
|
706
|
+
reset() unless opt[:noreset]
|
707
|
+
end
|
708
|
+
|
709
|
+
#
|
710
|
+
# with csv file
|
711
|
+
# ["foo.csv","1:2","title","with","axes"]
|
712
|
+
#
|
713
|
+
# with csv string
|
714
|
+
# ["1,2\n2,3\n4,5","1:2","title","with","axes"]
|
715
|
+
#
|
716
|
+
def plot (*argv, &block)
|
717
|
+
@init.call if @init
|
718
|
+
plots, opt = parse_args(argv, &block)
|
719
|
+
@last = plots + [opt]
|
720
|
+
with_tempfile(plots.size) { |*tempfile|
|
721
|
+
plot_list = []
|
722
|
+
plots.each_with_index do |arg, i|
|
723
|
+
arg = arg.clone
|
724
|
+
local_ranges = []
|
725
|
+
loop do
|
726
|
+
case arg.first
|
727
|
+
when Range
|
728
|
+
rng = arg.shift
|
729
|
+
local_ranges << "[" + [rng.begin,rng.end].join(":") + "] "
|
730
|
+
when Hash
|
731
|
+
var,rng = arg.shift.first
|
732
|
+
case var
|
733
|
+
when :x
|
734
|
+
local_ranges[0] = "[" + [rng.begin,rng.end].join(":") + "] "
|
735
|
+
when :y
|
736
|
+
local_ranges[1] = "[" + [rng.begin,rng.end].join(":") + "] "
|
737
|
+
when :z
|
738
|
+
local_ranges[2] = "[" + [rng.begin,rng.end].join(":") + "] "
|
739
|
+
else
|
740
|
+
local_ranges << "[#{var}=" + [rng.begin,rng.end].join(":") + "] "
|
741
|
+
end
|
742
|
+
else
|
743
|
+
break
|
744
|
+
end
|
745
|
+
end
|
746
|
+
if i == 0 and not local_ranges.empty?
|
747
|
+
local_ranges.unshift "sample"
|
748
|
+
end
|
749
|
+
local_ranges = local_ranges.map{|v| v.nil? ? "[:]" : v }
|
750
|
+
if arg.first.is_a?(Symbol) and arg.first == :newhistogram
|
751
|
+
arg.shift
|
752
|
+
arg, dataspec, using, title, with, axis = *parse_data(arg)
|
753
|
+
plot_cmd = [
|
754
|
+
"newhistogram",
|
755
|
+
using ? using : "",
|
756
|
+
title ? title : "",
|
757
|
+
with ? with : "",
|
758
|
+
]
|
759
|
+
elsif arg.first.is_a?(DataBlock)
|
760
|
+
datablock = arg.shift
|
761
|
+
if datablock.is_csv?
|
762
|
+
put("set datafile separator ','")
|
763
|
+
end
|
764
|
+
arg, dataspec, using, title, with, axis = *parse_data(arg)
|
765
|
+
plot_cmd = local_ranges + [
|
766
|
+
datablock.name,
|
767
|
+
dataspec ? dataspec : "",
|
768
|
+
@gnuplot_version >= 4.4 ? "volatile" : "",
|
769
|
+
opt[:using] ? "using " + opt[:using] :
|
770
|
+
using ? using : "",
|
771
|
+
axis ? "axes #{axis}" : "",
|
772
|
+
with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
|
773
|
+
title ? "title #{title}" : ""
|
774
|
+
]
|
775
|
+
elsif arg.first.is_a?(String)
|
776
|
+
file = arg.shift
|
777
|
+
if file =~ /\.(png|jpg)\z/
|
778
|
+
arg, dataspec, using, title, with, axis = *parse_data(arg)
|
779
|
+
plot_cmd = local_ranges + [
|
780
|
+
"'#{file}'",
|
781
|
+
dataspec ? dataspec : "",
|
782
|
+
"binary filetype=auto",
|
783
|
+
@gnuplot_version >= 4.4 ? "volatile" : "",
|
784
|
+
opt[:using] ? "using " + opt[:using] :
|
785
|
+
using ? using : "",
|
786
|
+
axis ? "axes #{axis}" : "",
|
787
|
+
with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
|
788
|
+
title ? "title #{title}" : ""
|
789
|
+
]
|
790
|
+
else
|
791
|
+
if file == ""
|
792
|
+
elsif file =~ /,/ or file =~ /[\n\r]/
|
793
|
+
if file =~ /,/
|
794
|
+
put("set datafile separator ','")
|
795
|
+
end
|
796
|
+
file = file.gsub(/UNDEF/, "NaN")
|
797
|
+
open(tempfile[i], "w") { |io| io.write file }
|
798
|
+
file = tempfile[i]
|
799
|
+
else
|
800
|
+
unless File.exist?(file)
|
801
|
+
raise "can't open file #{file} for plot2d"
|
802
|
+
end
|
803
|
+
end
|
804
|
+
arg, dataspec, using, title, with, axis = *parse_data(arg)
|
805
|
+
plot_cmd = local_ranges + [
|
806
|
+
"'#{file}'",
|
807
|
+
dataspec ? dataspec : "",
|
808
|
+
@gnuplot_version >= 4.4 ? "volatile" : "",
|
809
|
+
opt[:using] ? "using " + opt[:using] :
|
810
|
+
using ? using : "",
|
811
|
+
axis ? "axes #{axis}" : "",
|
812
|
+
with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
|
813
|
+
title ? "title #{title}" : ""
|
814
|
+
]
|
815
|
+
end
|
816
|
+
elsif arg.first.is_a?(Array)
|
817
|
+
funcs, dataspec, using, title, with, axis = *parse_data(arg)
|
818
|
+
plot_cmd = local_ranges + [
|
819
|
+
funcs.join(","),
|
820
|
+
dataspec ? dataspec : "",
|
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
|
+
else
|
828
|
+
arg, dataspec, using, title, with, axis = *parse_data(arg)
|
829
|
+
arg = arg.map{|x| CArray.wrap_readonly(x, CA_DOUBLE) }
|
830
|
+
if with.to_s =~ /rgbimage/ or opt[:with].to_s =~ /rgbimage/
|
831
|
+
if arg[2] and arg[2].rank >= 2 and
|
832
|
+
( arg[2].size != arg[0].size or arg[2].size != arg[1].size )
|
833
|
+
xlen = arg[0].size
|
834
|
+
ylen = arg[1].size
|
835
|
+
arg[0] = arg[0][ylen,:%]
|
836
|
+
arg[1] = arg[1][:%,xlen]
|
837
|
+
if arg[2].rank == 3
|
838
|
+
arg2 = arg[2]
|
839
|
+
arg[2] = arg2[nil,nil,0]
|
840
|
+
arg[3] = arg2[nil,nil,1]
|
841
|
+
arg[4] = arg2[nil,nil,2]
|
842
|
+
end
|
843
|
+
end
|
844
|
+
is_image = true
|
845
|
+
is_rgb = true
|
846
|
+
elsif with.to_s =~ /image/ or opt[:with].to_s =~ /image/
|
847
|
+
if arg[2] and arg[2].rank == 2 and
|
848
|
+
( arg[2].size != arg[0].size or arg[2].size != arg[1].size )
|
849
|
+
xlen = arg[0].size
|
850
|
+
ylen = arg[1].size
|
851
|
+
arg[0] = arg[0][ylen,:%]
|
852
|
+
arg[1] = arg[1][:%,xlen]
|
853
|
+
end
|
854
|
+
is_image = true
|
855
|
+
is_rgb = false
|
856
|
+
else
|
857
|
+
arg = arg.map{|x| x.rank > 1 ? x[nil] : x }
|
858
|
+
is_image = false
|
859
|
+
end
|
860
|
+
out = CArray.merge(CA_DOUBLE, arg, -1)
|
861
|
+
if is_image
|
862
|
+
if is_rgb
|
863
|
+
datalen = out.dim2
|
864
|
+
if arg.size == 1
|
865
|
+
datalen = 1
|
866
|
+
array = "(" + [out.dim1,out.dim0].join(',') + ")"
|
867
|
+
record = nil
|
868
|
+
else
|
869
|
+
datalen = 5
|
870
|
+
array = nil
|
871
|
+
record = "(" + [out.dim1,out.dim0].join(',') + ")"
|
872
|
+
end
|
873
|
+
else
|
874
|
+
if arg.size == 1
|
875
|
+
datalen = 1
|
876
|
+
array = "(" + [out.dim1,out.dim0].join(',') + ")"
|
877
|
+
record = nil
|
878
|
+
else
|
879
|
+
datalen = 3
|
880
|
+
array = nil
|
881
|
+
record = out.dim1*out.dim0
|
882
|
+
end
|
883
|
+
end
|
884
|
+
else
|
885
|
+
datalen = arg.size
|
886
|
+
record = out.dim0
|
887
|
+
array = nil
|
888
|
+
end
|
889
|
+
open(tempfile[i], "w") { |io|
|
890
|
+
out.unmask_copy(0.0/0.0).dump_binary(io)
|
891
|
+
}
|
892
|
+
plot_cmd = local_ranges + [
|
893
|
+
"'#{tempfile[i]}'",
|
894
|
+
"binary",
|
895
|
+
record ? "record=#{record}" : "",
|
896
|
+
array ? "array=#{array}" : "",
|
897
|
+
"format='#{'%double'*datalen}'",
|
898
|
+
dataspec ? dataspec : "",
|
899
|
+
@gnuplot_version >= 4.4 ? "volatile" : "",
|
900
|
+
opt[:using] ? "using " + opt[:using] :
|
901
|
+
using ? using :
|
902
|
+
"using " + "#{(1..datalen).map{|x|'%i' % x}.join(':')}",
|
903
|
+
axis ? "axes #{axis}" : "",
|
904
|
+
with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
|
905
|
+
title ? "title #{title}" : ""
|
906
|
+
]
|
907
|
+
end
|
908
|
+
plot_list.push(plot_cmd.join(" "))
|
909
|
+
end
|
910
|
+
opt.set(:margin, :title, :key, :bgcolor, :palette,
|
911
|
+
:timefmt, :xaxis, :x2axis, :yaxis, :y2axis,
|
912
|
+
:cbaxis, :grid, :border, :parametric,
|
913
|
+
:options)
|
914
|
+
put("plot " + plot_list.join(","))
|
915
|
+
if @multiplot_mode
|
916
|
+
@multiplot_plot_number += 1
|
917
|
+
end
|
918
|
+
pause() unless opt[:nopause]
|
919
|
+
reset() unless opt[:noreset]
|
920
|
+
}
|
921
|
+
end
|
922
|
+
|
923
|
+
alias scatter plot
|
924
|
+
alias plot2d plot
|
925
|
+
|
926
|
+
def splot (*argv, &block)
|
927
|
+
@init.call if @init
|
928
|
+
plots, opt = parse_args(argv, &block)
|
929
|
+
@last = plots + [opt]
|
930
|
+
with_tempfile(plots.size) { |*tempfile|
|
931
|
+
plot_list = []
|
932
|
+
plots.each_with_index do |arg, i|
|
933
|
+
arg = arg.clone
|
934
|
+
local_ranges = []
|
935
|
+
loop do
|
936
|
+
case arg.first
|
937
|
+
when Range
|
938
|
+
rng = arg.shift
|
939
|
+
local_ranges << "[" + [rng.begin,rng.end].join(":") + "] "
|
940
|
+
when Hash
|
941
|
+
var,rng = arg.shift.first
|
942
|
+
case var
|
943
|
+
when :x
|
944
|
+
local_ranges[0] = "[" + [rng.begin,rng.end].join(":") + "] "
|
945
|
+
when :y
|
946
|
+
local_ranges[1] = "[" + [rng.begin,rng.end].join(":") + "] "
|
947
|
+
when :z
|
948
|
+
local_ranges[2] = "[" + [rng.begin,rng.end].join(":") + "] "
|
949
|
+
else
|
950
|
+
local_ranges << "[#{var}=" + [rng.begin,rng.end].join(":") + "] "
|
951
|
+
end
|
952
|
+
else
|
953
|
+
break
|
954
|
+
end
|
955
|
+
end
|
956
|
+
if i == 0 and not local_ranges.empty?
|
957
|
+
local_ranges.unshift "sample"
|
958
|
+
end
|
959
|
+
local_ranges = local_ranges.map{|v| v.nil? ? "[:]" : v }
|
960
|
+
if arg.first.is_a?(DataBlock)
|
961
|
+
datablock = arg.shift
|
962
|
+
if datablock.is_csv?
|
963
|
+
put("set datafile separator ','")
|
964
|
+
end
|
965
|
+
arg, dataspec, using, title, with, axis = *parse_data(arg)
|
966
|
+
plot_cmd = local_ranges + [
|
967
|
+
datablock.name,
|
968
|
+
dataspec ? dataspec : "",
|
969
|
+
@gnuplot_version >= 4.4 ? "volatile" : "",
|
970
|
+
opt[:using] ? "using " + opt[:using] :
|
971
|
+
using ? using : "",
|
972
|
+
axis ? "axes #{axis}" : "",
|
973
|
+
with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
|
974
|
+
title ? "title #{title}" : ""
|
975
|
+
]
|
976
|
+
elsif arg.first.is_a?(String)
|
977
|
+
file = arg.shift
|
978
|
+
if file =~ /\.(png|jpg)\z/
|
979
|
+
arg, dataspec, using, title, with, axis = *parse_data(arg)
|
980
|
+
plot_cmd = [
|
981
|
+
"'#{file}'",
|
982
|
+
dataspec ? dataspec : "",
|
983
|
+
"binary filetype=auto",
|
984
|
+
@gnuplot_version >= 4.4 ? "volatile" : "",
|
985
|
+
opt[:using] ? "using " + opt[:using] :
|
986
|
+
using ? using : "",
|
987
|
+
axis ? "axes #{axis}" : "",
|
988
|
+
with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
|
989
|
+
title ? "title #{title}" : ""
|
990
|
+
]
|
991
|
+
else
|
992
|
+
if file == ""
|
993
|
+
elsif file =~ /,/ or file =~ /[\n\r]/
|
994
|
+
if file =~ /,/
|
995
|
+
put("set datafile separator ','")
|
996
|
+
end
|
997
|
+
file = file.gsub(/UNDEF/, "NaN")
|
998
|
+
open(tempfile[i], "w") { |io| io.write file }
|
999
|
+
file = tempfile[i]
|
1000
|
+
else
|
1001
|
+
unless File.exist?(file)
|
1002
|
+
raise "can't open file #{file} for splot"
|
1003
|
+
end
|
1004
|
+
end
|
1005
|
+
arg, dataspec, using, title, with, axis = *parse_data(arg)
|
1006
|
+
plot_cmd = [
|
1007
|
+
"'#{file}'",
|
1008
|
+
dataspec ? dataspec : "",
|
1009
|
+
@gnuplot_version >= 4.4 ? "volatile" : "",
|
1010
|
+
opt[:using] ? "using " + opt[:using] :
|
1011
|
+
using ? using : "",
|
1012
|
+
axis ? "axes #{axis}" : "",
|
1013
|
+
with ? "with #{with}"
|
1014
|
+
: opt[:with] ? "with #{opt[:with]}" : "",
|
1015
|
+
title ? "title #{title}" : ""
|
1016
|
+
]
|
1017
|
+
end
|
1018
|
+
elsif arg.first.is_a?(Array)
|
1019
|
+
funcs, dataspec, using, title, with, axis = *parse_data(arg)
|
1020
|
+
plot_cmd = [
|
1021
|
+
funcs.join(","),
|
1022
|
+
dataspec ? dataspec : "",
|
1023
|
+
opt[:using] ? "using " + opt[:using] :
|
1024
|
+
using ? using : "",
|
1025
|
+
axis ? "axes #{axis}" : "",
|
1026
|
+
with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
|
1027
|
+
title ? "title #{title}" : ""
|
1028
|
+
]
|
1029
|
+
else
|
1030
|
+
arg, dataspec, using, title, with, axis = *parse_data(arg)
|
1031
|
+
arg = arg.map{|x| CArray.wrap_readonly(x, CA_DOUBLE) }
|
1032
|
+
if arg[2] and arg[2].rank == 2 and
|
1033
|
+
( arg[2].size != arg[0].size or arg[2].size != arg[1].size )
|
1034
|
+
xlen = arg[0].size
|
1035
|
+
ylen = arg[1].size
|
1036
|
+
arg[0] = arg[0][ylen,:%]
|
1037
|
+
arg[1] = arg[1][:%,xlen]
|
1038
|
+
is_image = true
|
1039
|
+
elsif arg[0] and arg[0].rank == 2
|
1040
|
+
is_image = true
|
1041
|
+
elsif arg[0] and arg[0].rank == 3
|
1042
|
+
is_image = true
|
1043
|
+
else
|
1044
|
+
is_image = false
|
1045
|
+
end
|
1046
|
+
out = CArray.merge(CA_DOUBLE, arg, -1)
|
1047
|
+
if is_image
|
1048
|
+
datalen = out.dim2
|
1049
|
+
record = "(" + [out.dim1,out.dim0].join(",") + ")"
|
1050
|
+
else
|
1051
|
+
datalen = arg.size
|
1052
|
+
record = out.dim0
|
1053
|
+
end
|
1054
|
+
open(tempfile[i], "w") { |io|
|
1055
|
+
out.unmask_copy(0.0/0.0).dump_binary(io)
|
1056
|
+
}
|
1057
|
+
plot_cmd = local_ranges + [
|
1058
|
+
"'#{tempfile[i]}'",
|
1059
|
+
"binary",
|
1060
|
+
record ? "record=#{record}" : "",
|
1061
|
+
"format='#{'%double'*datalen}'",
|
1062
|
+
dataspec ? dataspec : "",
|
1063
|
+
@gnuplot_version >= 4.4 ? "volatile" : "",
|
1064
|
+
opt[:using] ? "using " + opt[:using] :
|
1065
|
+
using ? using :
|
1066
|
+
"using " + "#{(1..datalen).map{|x|'%i' % x}.join(':')}",
|
1067
|
+
axis ? "axes #{axis}" : "",
|
1068
|
+
with ? "with #{with}" : opt[:with] ? "with #{opt[:with]}" : "",
|
1069
|
+
title ? "title #{title}" : ""
|
1070
|
+
]
|
1071
|
+
end
|
1072
|
+
plot_list.push(plot_cmd.join(" "))
|
1073
|
+
end
|
1074
|
+
opt.set(:margin, :title, :key, :bgcolor, :view, :palette,
|
1075
|
+
:timefmt, :xaxis, :yaxis, :zaxis,
|
1076
|
+
:cbaxis, :border, :parametric, :options)
|
1077
|
+
put("splot " + plot_list.join(","))
|
1078
|
+
if @multiplot_mode
|
1079
|
+
@multiplot_plot_number += 1
|
1080
|
+
end
|
1081
|
+
pause() unless opt[:nopause]
|
1082
|
+
reset() unless opt[:noreset]
|
1083
|
+
}
|
1084
|
+
end
|
1085
|
+
|
1086
|
+
alias scatter3d splot
|
1087
|
+
alias mesh3d splot
|
1088
|
+
alias grid3d splot
|
1089
|
+
|
1090
|
+
def image (*argv, &block)
|
1091
|
+
raise "image() will be obsolete, use plot(..., :with=>'(rgb)image')"
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
def imagemap (*argv, &block)
|
1095
|
+
raise "imagemap() will be obsolete, use plot(..., :with=>'(rgb)image')"
|
1096
|
+
end
|
1097
|
+
|
1098
|
+
#
|
1099
|
+
# fit(function, params, data, options)
|
1100
|
+
#
|
1101
|
+
#
|
1102
|
+
# with csv file
|
1103
|
+
# ["foo.csv","1:2","title","with","axes"]
|
1104
|
+
#
|
1105
|
+
# with csv string
|
1106
|
+
# ["1,2\n2,3\n4,5","1:2","title","with","axes"]
|
1107
|
+
#
|
1108
|
+
def fit (expr, params, data, opt = {})
|
1109
|
+
with_tempfile(2) { |tempfile, logfile|
|
1110
|
+
if data.first.is_a?(DataBlock)
|
1111
|
+
datablock = data.shift
|
1112
|
+
if datablock.is_csv?
|
1113
|
+
put("set datafile separator ','")
|
1114
|
+
end
|
1115
|
+
using = data.shift
|
1116
|
+
fitdata = [
|
1117
|
+
datablock.name,
|
1118
|
+
using ? "using " + using :
|
1119
|
+
opt[:using] ? "using " + opt[:using] : "",
|
1120
|
+
]
|
1121
|
+
elsif data.first.is_a?(String)
|
1122
|
+
file = data.shift
|
1123
|
+
if file =~ /,/ or file =~ /[\n\r]/
|
1124
|
+
if file =~ /,/
|
1125
|
+
put("set datafile separator ','")
|
1126
|
+
end
|
1127
|
+
open(tempfile, "w") { |io| io.write file }
|
1128
|
+
file = tempfile
|
1129
|
+
else
|
1130
|
+
unless File.exist?(file)
|
1131
|
+
raise "can't open file #{file} for plot2d"
|
1132
|
+
end
|
1133
|
+
end
|
1134
|
+
using = data.shift
|
1135
|
+
fitdata = [
|
1136
|
+
"'#{file}'",
|
1137
|
+
using ? "using " + using :
|
1138
|
+
opt[:using] ? "using " + opt[:using] : "",
|
1139
|
+
]
|
1140
|
+
else
|
1141
|
+
arg = data.map{|x| CArray.wrap_readonly(x, CA_DOUBLE) }
|
1142
|
+
if arg[2] and arg[2].rank == 2 and
|
1143
|
+
( arg[2].size != arg[0].size or arg[2].size != arg[1].size )
|
1144
|
+
xlen = arg[0].size
|
1145
|
+
ylen = arg[1].size
|
1146
|
+
arg[0] = arg[0][ylen,:%]
|
1147
|
+
arg[1] = arg[1][:%,xlen]
|
1148
|
+
record = arg[0].dim1
|
1149
|
+
elsif arg[0] and arg[0].rank == 2
|
1150
|
+
record = arg[0].dim1
|
1151
|
+
else
|
1152
|
+
record = arg[0].dim0
|
1153
|
+
end
|
1154
|
+
datalen = arg.size
|
1155
|
+
out = CArray.merge(CA_DOUBLE, arg, -1)
|
1156
|
+
open(tempfile, "w") { |io|
|
1157
|
+
out.unmask_copy(0.0/0.0).dump_binary(io)
|
1158
|
+
}
|
1159
|
+
fitdata = [
|
1160
|
+
"'#{tempfile}'",
|
1161
|
+
"binary",
|
1162
|
+
record ? "record=#{record}" : "",
|
1163
|
+
"format='#{'%double'*datalen}'",
|
1164
|
+
"using " + ( opt[:using] ||
|
1165
|
+
"#{(1..datalen).map{|x|'($%i)' % x}.join(':')}" ),
|
1166
|
+
]
|
1167
|
+
end
|
1168
|
+
if opt[:ranges]
|
1169
|
+
ranges = opt[:ranges]
|
1170
|
+
else
|
1171
|
+
ranges = ""
|
1172
|
+
end
|
1173
|
+
set("fit logfile '#{logfile}' errorvariables covariancevariables")
|
1174
|
+
put("fit #{ranges} #{expr} #{fitdata.join(" ")} via " + params.map{|x| x.to_s}.join(","))
|
1175
|
+
res = OpenStruct.new
|
1176
|
+
res.expression = expr
|
1177
|
+
res.parameters = params
|
1178
|
+
result_params = put("print " + params.map{|x| x.to_s}.join(",")).split.map{|_x| _x.to_f}
|
1179
|
+
result_err = put("print " + params.map{|x| x.to_s + "_err"}.join(",")).split.map{|_x| _x.to_f}
|
1180
|
+
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}
|
1181
|
+
params.each_with_index do |name, i|
|
1182
|
+
res.send(name.to_s+"=", result_params[i])
|
1183
|
+
res.send(name.to_s+"_err=", result_err[i])
|
1184
|
+
end
|
1185
|
+
i=0
|
1186
|
+
params.each do |x|
|
1187
|
+
params.each do |y|
|
1188
|
+
res.send("cov_" + x.to_s + "_" + y.to_s + "=", result_cov[i])
|
1189
|
+
end
|
1190
|
+
i+=1
|
1191
|
+
end
|
1192
|
+
res.log = File.read(logfile)
|
1193
|
+
result = put("print FIT_NDF, FIT_WSSR, FIT_STDFIT, FIT_P")
|
1194
|
+
res.ndf, res.wssr, res.stdfit, res.fit_p = result.split.map{|_x| _x.to_f}
|
1195
|
+
|
1196
|
+
return result_params, res
|
1197
|
+
}
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
#
|
1201
|
+
# my_palette = [[0, '#ffffff'],
|
1202
|
+
# [1, '#909090'],
|
1203
|
+
# [5, '#000090'],
|
1204
|
+
# [10, '#000fff'],
|
1205
|
+
# [25, '#0090ff'],
|
1206
|
+
# [50, '#0fffee'],
|
1207
|
+
# [75, '#90ff70'],
|
1208
|
+
# [100,'#ffee00'],
|
1209
|
+
# [200,'#ff7000'],
|
1210
|
+
# [300,'#ee0000'],
|
1211
|
+
# [400,'#7f0000']]
|
1212
|
+
# index = gp.set_palette_discrete(depth, my_palette)
|
1213
|
+
def set_palette_discrete (data, my_palette, option = {})
|
1214
|
+
default = { :model=>"RGB",
|
1215
|
+
:continuous=>false,
|
1216
|
+
:lower=>nil,
|
1217
|
+
:upper=>nil,
|
1218
|
+
:lower_label=>false,
|
1219
|
+
:upper_label=>false }
|
1220
|
+
option = default.update(option)
|
1221
|
+
model, continuous, lower, lower_label, upper, upper_label =
|
1222
|
+
option.values_at(:model, :continuous, :lower, :lower_label, :upper, :upper_label)
|
1223
|
+
levels = my_palette.size
|
1224
|
+
scale = my_palette.map{|r| r[0] }
|
1225
|
+
scalec = scale.clone
|
1226
|
+
color = my_palette.map{|r| r[1] }
|
1227
|
+
out = []
|
1228
|
+
cbmin = 0
|
1229
|
+
cbmax = levels - 1
|
1230
|
+
maxcolors = levels-1
|
1231
|
+
if continuous
|
1232
|
+
if lower
|
1233
|
+
out << [-1, %{'#{lower}'}]
|
1234
|
+
cbmin = -1
|
1235
|
+
maxcolors += 1
|
1236
|
+
end
|
1237
|
+
(levels).times do |i|
|
1238
|
+
level = i
|
1239
|
+
out << [level, %{'#{color[i]}'}]
|
1240
|
+
end
|
1241
|
+
if upper
|
1242
|
+
out << [levels, %{'#{upper}'}]
|
1243
|
+
cbmax = levels
|
1244
|
+
maxcolors += 1
|
1245
|
+
end
|
1246
|
+
else
|
1247
|
+
if lower
|
1248
|
+
out << [-1, %{'#{lower}'}]
|
1249
|
+
out << [0, %{'#{lower}'}]
|
1250
|
+
cbmin = -1
|
1251
|
+
maxcolors += 1
|
1252
|
+
end
|
1253
|
+
(levels-1).times do |i|
|
1254
|
+
level = i
|
1255
|
+
level1 = i+1
|
1256
|
+
out << [level, %{'#{color[i]}'}]
|
1257
|
+
out << [level1, %{'#{color[i]}'}]
|
1258
|
+
end
|
1259
|
+
if upper
|
1260
|
+
out << [levels-1, %{'#{upper}'}]
|
1261
|
+
out << [levels, %{'#{upper}'}]
|
1262
|
+
cbmax = levels
|
1263
|
+
maxcolors += 1
|
1264
|
+
end
|
1265
|
+
end
|
1266
|
+
put ["set palette model #{model} maxcolors #{maxcolors} defined (\\",
|
1267
|
+
out.map{|list| " " + list.join(" ")}.join(",\\\n") + "\\",
|
1268
|
+
")"].join("\n")
|
1269
|
+
out = []
|
1270
|
+
if lower and lower_label
|
1271
|
+
out << [%{''{/Symbol <}#{scale.first}'}, cbmin]
|
1272
|
+
end
|
1273
|
+
scale.each_with_index do |s, i|
|
1274
|
+
out << [%{'#{s}'}, i]
|
1275
|
+
end
|
1276
|
+
if upper and upper_label
|
1277
|
+
out << [%{'{/Symbol \\263}#{scale.last}'}, cbmax]
|
1278
|
+
end
|
1279
|
+
put %{ set cbtics (#{out.map {|d| d.join(" ")}.join(",")}) }
|
1280
|
+
put %{ set cbrange [#{cbmin}:#{cbmax}] }
|
1281
|
+
return CA_DOUBLE(scale).section(data)
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
#
|
1285
|
+
def set_xtics_monthly (start, last, fmt = nil, interval=nil, linewidth = 1, style = "lc rgb 'black' back")
|
1286
|
+
unless fmt
|
1287
|
+
fmt = "%b"
|
1288
|
+
end
|
1289
|
+
unless interval
|
1290
|
+
interval = 3
|
1291
|
+
end
|
1292
|
+
case start
|
1293
|
+
when String
|
1294
|
+
start = DateTime.parse(start)
|
1295
|
+
end
|
1296
|
+
case last
|
1297
|
+
when String
|
1298
|
+
last = DateTime.parse(last)
|
1299
|
+
end
|
1300
|
+
if interval < 0
|
1301
|
+
start = DateTime.parse(start.strftime("%Y-%m-01")) + 0.5
|
1302
|
+
last = (DateTime.parse(last.strftime("%Y-%m-01"))) + 0.5 >> 1
|
1303
|
+
else
|
1304
|
+
start = DateTime.parse(start.strftime("%Y-%m-01"))
|
1305
|
+
last = (DateTime.parse(last.strftime("%Y-%m-01"))) >> 1
|
1306
|
+
end
|
1307
|
+
set %{ xrange [#{time(start)}:#{time(last)}] }
|
1308
|
+
if linewidth > 0
|
1309
|
+
set %{ xtics ("" 0) scale 0,2 mirror }
|
1310
|
+
set %{ x2tics ("" 0) scale 0,1 mirror }
|
1311
|
+
else
|
1312
|
+
set %{ xtics ("" 0) scale 0,0 mirror }
|
1313
|
+
set %{ x2tics ("" 0) scale 0,0 mirror }
|
1314
|
+
end
|
1315
|
+
d = start
|
1316
|
+
while d <= last
|
1317
|
+
set %{ xtics add ('' #{time(d)} 1) }
|
1318
|
+
set %{ xtics add ('#{d.strftime(fmt)}' #{time(d+15)} 0) }
|
1319
|
+
case interval
|
1320
|
+
when -2,2
|
1321
|
+
set %{ x2tics add ('' #{time(d+15)} 1) }
|
1322
|
+
when -3,3
|
1323
|
+
set %{ x2tics add ('' #{time(d+10)} 1) }
|
1324
|
+
set %{ x2tics add ('' #{time(d+20)} 1) }
|
1325
|
+
when -6,6
|
1326
|
+
set %{ x2tics add ('' #{time(d+5)} 1) }
|
1327
|
+
set %{ x2tics add ('' #{time(d+10)} 1) }
|
1328
|
+
set %{ x2tics add ('' #{time(d+15)} 1) }
|
1329
|
+
set %{ x2tics add ('' #{time(d+20)} 1) }
|
1330
|
+
set %{ x2tics add ('' #{time(d+25)} 1) }
|
1331
|
+
else
|
1332
|
+
end
|
1333
|
+
d >>= 1
|
1334
|
+
end
|
1335
|
+
if linewidth > 0
|
1336
|
+
d = start >> 1
|
1337
|
+
while d < last
|
1338
|
+
set %{ arrow nohead from #{time(d)}, graph 0
|
1339
|
+
rto graph 0, graph 1 #{style} }
|
1340
|
+
d >>= 1
|
1341
|
+
end
|
1342
|
+
end
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
class DataBlock
|
1346
|
+
|
1347
|
+
@@datablock_count = 0
|
1348
|
+
|
1349
|
+
def initialize (processor, *args)
|
1350
|
+
put_ok = false
|
1351
|
+
if args.size == 1 and args.first.is_a?(Symbol)
|
1352
|
+
@name = "$" + args.first.to_s
|
1353
|
+
@text = processor.put %{ print #{@name}}
|
1354
|
+
elsif args.size == 1 and args.first.is_a?(String)
|
1355
|
+
@@datablock_count += 1
|
1356
|
+
@name = "$DBLK_#{@@datablock_count}"
|
1357
|
+
@text = args.first.dup
|
1358
|
+
put_ok = true
|
1359
|
+
else
|
1360
|
+
@@datablock_count += 1
|
1361
|
+
@name = "$DBLK_#{@@datablock_count}"
|
1362
|
+
@text = CArray.join(*args).to_csv
|
1363
|
+
@text.gsub!(/UNDEF/,"NaN")
|
1364
|
+
put_ok = true
|
1365
|
+
end
|
1366
|
+
@text.strip!
|
1367
|
+
@text.chomp!
|
1368
|
+
if put_ok
|
1369
|
+
processor.put %{
|
1370
|
+
#{@name} <<__EOD__
|
1371
|
+
#{@text}
|
1372
|
+
__EOD__
|
1373
|
+
}
|
1374
|
+
end
|
1375
|
+
end
|
1376
|
+
|
1377
|
+
def is_csv?
|
1378
|
+
return (@text =~ /,/)
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
def to_s
|
1382
|
+
return @text.dup
|
1383
|
+
end
|
1384
|
+
|
1385
|
+
def to_ca
|
1386
|
+
data = []
|
1387
|
+
@text.each_line do |line|
|
1388
|
+
case line
|
1389
|
+
when /^#/
|
1390
|
+
else
|
1391
|
+
data << line.strip.split(/ +/)
|
1392
|
+
end
|
1393
|
+
end
|
1394
|
+
return CA_OBJECT(data)
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
attr_reader :name, :text
|
1398
|
+
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
def datablock (*args)
|
1402
|
+
return DataBlock.new(self, *args)
|
1403
|
+
end
|
1404
|
+
|
1405
|
+
class Option # :nodoc:
|
1406
|
+
|
1407
|
+
def initialize (processor, option)
|
1408
|
+
@processor = processor
|
1409
|
+
@o = option
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
def set (*names)
|
1413
|
+
names.each do |name|
|
1414
|
+
self.send("set_#{name}")
|
1415
|
+
end
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
def [] (name)
|
1419
|
+
@o[name]
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
def []= (name, value)
|
1423
|
+
@o[name] = value
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
def update (hash)
|
1427
|
+
@o.update(hash)
|
1428
|
+
end
|
1429
|
+
|
1430
|
+
private
|
1431
|
+
|
1432
|
+
def put (*lines)
|
1433
|
+
return @processor.put(*lines)
|
1434
|
+
end
|
1435
|
+
|
1436
|
+
def evaluate (expr)
|
1437
|
+
return @processor.evaluate(expr)
|
1438
|
+
end
|
1439
|
+
|
1440
|
+
def set_title
|
1441
|
+
textcolor = @o[:fgcolor] ? "textcolor rgb \"#{@o[:fgcolor]}\"" : ""
|
1442
|
+
if @o[:title]
|
1443
|
+
put('set title "' + @o[:title] + '" ' + textcolor)
|
1444
|
+
end
|
1445
|
+
end
|
1446
|
+
|
1447
|
+
def set_key
|
1448
|
+
# ver = evaluate("GPVAL_VERSION")
|
1449
|
+
# if ver.to_f <= 4.2
|
1450
|
+
# tc = ""
|
1451
|
+
# else
|
1452
|
+
# tc = @o[:fgcolor] ? "tc rgb \"#{@o[:fgcolor]}\"" : ""
|
1453
|
+
# end
|
1454
|
+
# put("set key #{tc}")
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
def set_bgcolor
|
1458
|
+
if @o[:framecolor]
|
1459
|
+
put "set object rect from screen 0, screen 0 " \
|
1460
|
+
"to screen 1, screen 1 behind " \
|
1461
|
+
"fc rgb '#{@o[:framecolor]}' " \
|
1462
|
+
"fillstyle solid 1.0 noborder"
|
1463
|
+
end
|
1464
|
+
if @o[:shadowcolor]
|
1465
|
+
put "set object rect from graph 0.01, graph -0.02 " \
|
1466
|
+
"to graph 1.01, graph 0.98 behind " \
|
1467
|
+
"fc rgb '#{@o[:shadowcolor]}' " \
|
1468
|
+
"fillstyle solid 1.0 noborder"
|
1469
|
+
end
|
1470
|
+
if @o[:bgcolor]
|
1471
|
+
put "set object rect from graph 0, graph 0 " \
|
1472
|
+
"to graph 1, graph 1 behind " \
|
1473
|
+
"fc rgb '#{@o[:bgcolor]}' " \
|
1474
|
+
"fillstyle solid 1.0 noborder"
|
1475
|
+
end
|
1476
|
+
end
|
1477
|
+
|
1478
|
+
def set_border
|
1479
|
+
if @o[:noborder]
|
1480
|
+
put("unset border")
|
1481
|
+
end
|
1482
|
+
if @o[:noaxis]
|
1483
|
+
put("unset xtics")
|
1484
|
+
put("unset ytics")
|
1485
|
+
put("unset ztics")
|
1486
|
+
put("unset xlabel")
|
1487
|
+
put("unset ylabel")
|
1488
|
+
put("unset zlabel")
|
1489
|
+
return
|
1490
|
+
end
|
1491
|
+
if @o[:fgcolor]
|
1492
|
+
put("set border linecolor rgb \"#{@o[:fgcolor]}\" ")
|
1493
|
+
if @o[:zeroaxis]
|
1494
|
+
put("set xzeroaxis linecolor rgb \"#{@o[:fgcolor]}\" ")
|
1495
|
+
put("set yzeroaxis linecolor rgb \"#{@o[:fgcolor]}\" ")
|
1496
|
+
end
|
1497
|
+
else
|
1498
|
+
if @o[:zeroaxis]
|
1499
|
+
put("set xzeroaxis",
|
1500
|
+
"set yzeroaxis")
|
1501
|
+
end
|
1502
|
+
end
|
1503
|
+
end
|
1504
|
+
|
1505
|
+
def set_axis(axis)
|
1506
|
+
label, range, fmt, tics, mtics, ticsopts = *@o[axis]
|
1507
|
+
logscale = @o["#{axis}log".intern]
|
1508
|
+
timescale = @o["#{axis}time".intern]
|
1509
|
+
reverse = @o["#{axis}reverse".intern]
|
1510
|
+
textcolor = @o[:fgcolor] ? "textcolor rgb \"#{@o[:fgcolor]}\"" : ""
|
1511
|
+
if label
|
1512
|
+
put("set #{axis}label " + %{ "#{label} "} + textcolor)
|
1513
|
+
else
|
1514
|
+
put("unset #{axis}label")
|
1515
|
+
end
|
1516
|
+
if timescale
|
1517
|
+
put("set #{axis}data time")
|
1518
|
+
end
|
1519
|
+
if range
|
1520
|
+
case range
|
1521
|
+
when Range
|
1522
|
+
put("set #{axis}range [" + [range.begin,range.end].join(":") + "] " +
|
1523
|
+
( reverse ? "reverse " : "" ))
|
1524
|
+
when Array
|
1525
|
+
srange = range.join(":")
|
1526
|
+
put("set #{axis}range [" + srange + "] " + ( reverse ? "reverse " : "" ))
|
1527
|
+
else
|
1528
|
+
raise "invalid range specification"
|
1529
|
+
end
|
1530
|
+
else
|
1531
|
+
if reverse
|
1532
|
+
put("set #{axis}range [*:*] reverse")
|
1533
|
+
end
|
1534
|
+
end
|
1535
|
+
if tics
|
1536
|
+
if tics.is_a?(Array)
|
1537
|
+
ticslist = tics.collect do |v|
|
1538
|
+
v = [v].flatten
|
1539
|
+
case v.size
|
1540
|
+
when 1
|
1541
|
+
v.first.to_s
|
1542
|
+
else
|
1543
|
+
['"'+v[1].to_s+'"', v[0], v[2]||0].join(" ")
|
1544
|
+
end
|
1545
|
+
end.join(",")
|
1546
|
+
put("set #{axis}tics (#{ticslist}) #{textcolor} #{ticsopts}")
|
1547
|
+
else
|
1548
|
+
put("set #{axis}tics #{tics} #{textcolor} #{ticsopts}")
|
1549
|
+
end
|
1550
|
+
else
|
1551
|
+
put("set #{axis}tics #{textcolor} #{ticsopts}")
|
1552
|
+
end
|
1553
|
+
if mtics
|
1554
|
+
put("set m#{axis}tics #{mtics}")
|
1555
|
+
end
|
1556
|
+
if fmt
|
1557
|
+
put(%{ set format #{axis} "#{fmt}"})
|
1558
|
+
end
|
1559
|
+
if logscale
|
1560
|
+
put("set logscale #{axis}")
|
1561
|
+
end
|
1562
|
+
end
|
1563
|
+
|
1564
|
+
def set_xaxis
|
1565
|
+
set_axis(:x)
|
1566
|
+
end
|
1567
|
+
|
1568
|
+
def set_yaxis
|
1569
|
+
set_axis(:y)
|
1570
|
+
end
|
1571
|
+
|
1572
|
+
def set_x2axis
|
1573
|
+
if @o[:x2]
|
1574
|
+
set_axis(:x2)
|
1575
|
+
end
|
1576
|
+
end
|
1577
|
+
|
1578
|
+
def set_y2axis
|
1579
|
+
if @o[:y2]
|
1580
|
+
set_axis(:y2)
|
1581
|
+
end
|
1582
|
+
end
|
1583
|
+
|
1584
|
+
def set_zaxis
|
1585
|
+
set_axis(:z)
|
1586
|
+
end
|
1587
|
+
|
1588
|
+
def set_cbaxis
|
1589
|
+
set_axis(:cb)
|
1590
|
+
end
|
1591
|
+
|
1592
|
+
def set_grid
|
1593
|
+
if @o[:grid]
|
1594
|
+
linecolor = @o[:fgcolor] ? "linecolor rgb \"#{@o[:fgcolor]}\"" : ""
|
1595
|
+
case @o[:grid]
|
1596
|
+
when Array
|
1597
|
+
tics = @o[:grid].map{|a| "#{a}tics" }.join(" ")
|
1598
|
+
put("set grid #{tics} back linetype 0 #{linecolor}")
|
1599
|
+
else
|
1600
|
+
put("set grid xtics ytics y2tics back linetype 0 #{linecolor}")
|
1601
|
+
end
|
1602
|
+
end
|
1603
|
+
end
|
1604
|
+
|
1605
|
+
def set_options
|
1606
|
+
if @o[:ratio]
|
1607
|
+
put("set size ratio #{@o[:ratio]}")
|
1608
|
+
# put("set view equal xy")
|
1609
|
+
end
|
1610
|
+
end
|
1611
|
+
|
1612
|
+
def set_timefmt
|
1613
|
+
if @o[:timefmt]
|
1614
|
+
put("set timefmt \"#{@o[:timefmt]}\"")
|
1615
|
+
end
|
1616
|
+
end
|
1617
|
+
|
1618
|
+
def set_view
|
1619
|
+
if @o[:view]
|
1620
|
+
put("set view #{[@o[:view]].flatten.join(",")}")
|
1621
|
+
end
|
1622
|
+
end
|
1623
|
+
|
1624
|
+
def set_parametric
|
1625
|
+
if @o[:parametric]
|
1626
|
+
put("set parametric")
|
1627
|
+
end
|
1628
|
+
end
|
1629
|
+
|
1630
|
+
def set_margin
|
1631
|
+
if @o[:floating] or
|
1632
|
+
( @processor.multiplot_mode and
|
1633
|
+
( @processor.multiplot_option[:layout] or
|
1634
|
+
@processor.multiplot_option[:floating] ) )
|
1635
|
+
if @o[:nomargin]
|
1636
|
+
put("set lmargin 0",
|
1637
|
+
"set rmargin 0",
|
1638
|
+
"set tmargin 0",
|
1639
|
+
"set bmargin 0")
|
1640
|
+
end
|
1641
|
+
else
|
1642
|
+
put("set size 0.7, 0.7",
|
1643
|
+
"set origin 0.15, 0.15",
|
1644
|
+
"set lmargin 0",
|
1645
|
+
"set rmargin 0",
|
1646
|
+
"set tmargin 0",
|
1647
|
+
"set bmargin 0")
|
1648
|
+
end
|
1649
|
+
end
|
1650
|
+
|
1651
|
+
def set_palette (*argv)
|
1652
|
+
case @o[:palette]
|
1653
|
+
when Array
|
1654
|
+
list = @o[:palette].clone
|
1655
|
+
kind = list.shift
|
1656
|
+
Palette.set(@processor, kind.intern, *list)
|
1657
|
+
else
|
1658
|
+
Palette.set(@processor, @o[:palette])
|
1659
|
+
end
|
1660
|
+
end
|
1661
|
+
|
1662
|
+
end
|
1663
|
+
|
1664
|
+
def palette (kind, *argv)
|
1665
|
+
return Palette.set(self, kind, *argv)
|
1666
|
+
end
|
1667
|
+
|
1668
|
+
module Palette
|
1669
|
+
|
1670
|
+
def self.quote (text)
|
1671
|
+
case text
|
1672
|
+
when Symbol
|
1673
|
+
text.to_s
|
1674
|
+
when /^\{\{(.*)\}\}$/
|
1675
|
+
$1
|
1676
|
+
else
|
1677
|
+
text = text.clone
|
1678
|
+
if text[0, 1] == "\\"
|
1679
|
+
text[1..-1]
|
1680
|
+
else
|
1681
|
+
text.gsub!(/\n/, '\\n')
|
1682
|
+
text.gsub!(/\t/, '\\t')
|
1683
|
+
text.gsub!(/"/, '\\\\"')
|
1684
|
+
'"' + text + '"'
|
1685
|
+
end
|
1686
|
+
end
|
1687
|
+
end
|
1688
|
+
|
1689
|
+
def self.set (gp, kind, *argv)
|
1690
|
+
if argv.last.is_a?(Hash)
|
1691
|
+
opt = argv.pop
|
1692
|
+
else
|
1693
|
+
opt = {}
|
1694
|
+
end
|
1695
|
+
if opt[:model]
|
1696
|
+
gp.set %{ palette model #{opt[:model]} }
|
1697
|
+
end
|
1698
|
+
if opt[:maxcolors]
|
1699
|
+
gp.set %{ palette maxcolors #{opt[:maxcolors]} }
|
1700
|
+
end
|
1701
|
+
case kind
|
1702
|
+
when :defined
|
1703
|
+
self.set_palette_array(gp, argv)
|
1704
|
+
when :random
|
1705
|
+
n = argv.first || 10
|
1706
|
+
list = []
|
1707
|
+
n.times do |i|
|
1708
|
+
value = rand(256)*0x10000 + rand(256)*0x100 + rand(256)
|
1709
|
+
list << [i, "#%6x" % value]
|
1710
|
+
end
|
1711
|
+
self.set_palette_array(gp, list)
|
1712
|
+
when :rgbformulae
|
1713
|
+
set_palette_formula(gp, *argv[0,3])
|
1714
|
+
when :file
|
1715
|
+
set_palette_file(gp, argv.first)
|
1716
|
+
when :gmt
|
1717
|
+
set_palette_gmt(gp, argv.first, opt)
|
1718
|
+
when :cpt_city
|
1719
|
+
set_palette_cpt_city(gp, argv.first, opt)
|
1720
|
+
when Symbol
|
1721
|
+
set_palette_predefined(gp, kind)
|
1722
|
+
when String
|
1723
|
+
set_palette_string(gp, kind)
|
1724
|
+
when CArray
|
1725
|
+
set_palette_carray(gp, kind)
|
1726
|
+
when Array
|
1727
|
+
self.set_palette_array(gp, kind)
|
1728
|
+
when ColorPalette
|
1729
|
+
set_palette_color_palette(gp, kind)
|
1730
|
+
end
|
1731
|
+
end
|
1732
|
+
|
1733
|
+
def self.set_palette_formula (gp, *argv)
|
1734
|
+
gp.set 'palette rgbformulae ' + argv.join(', ')
|
1735
|
+
end
|
1736
|
+
|
1737
|
+
def self.set_palette_file (gp, *argv)
|
1738
|
+
gp.set 'palette file ' + quote(argv[0]) + " " + argv[1].to_s
|
1739
|
+
end
|
1740
|
+
|
1741
|
+
def self.set_palette_string (gp, string)
|
1742
|
+
gp.set "palette " + string
|
1743
|
+
end
|
1744
|
+
|
1745
|
+
def self.set_palette_array (gp, array)
|
1746
|
+
gp.set "palette " +
|
1747
|
+
'defined (' + array.map { |x|
|
1748
|
+
case x[1]
|
1749
|
+
when String
|
1750
|
+
[x[0], quote(x[1])].join(' ')
|
1751
|
+
else
|
1752
|
+
x.join(' ')
|
1753
|
+
end
|
1754
|
+
}.join(', ') + ')'
|
1755
|
+
end
|
1756
|
+
|
1757
|
+
def self.set_palette_carray (gp, ca)
|
1758
|
+
gp.instance_exec {
|
1759
|
+
with_tempfile(1) { |tmpfile|
|
1760
|
+
open(tmpfile, "w") {|io| ca.dump_binary(io)}
|
1761
|
+
if ca.rank == 1 or ( ca.rank == 2 and ca.dim1 == 1)
|
1762
|
+
set("palette file '#{tmpfile}' binary record=#{ca.dim0} using 1:1:1 model #{model}")
|
1763
|
+
elsif ca.rank == 2 and ca.dim1 == 3
|
1764
|
+
set("palette file '#{tmpfile}' binary record=#{ca.dim0} using 1:2:3 model #{model}")
|
1765
|
+
else
|
1766
|
+
raise "invalid palette specification"
|
1767
|
+
end
|
1768
|
+
}
|
1769
|
+
}
|
1770
|
+
end
|
1771
|
+
|
1772
|
+
def self.set_palette_color_palette (gp, pal)
|
1773
|
+
gp.put(pal.to_gnuplot)
|
1774
|
+
end
|
1775
|
+
|
1776
|
+
def self.set_palette_gmt (gp, name, opt)
|
1777
|
+
cpt = ColorPalette::CPT(name, :continuous=>opt[:continuous])
|
1778
|
+
if opt[:use_scale]
|
1779
|
+
min, max = cpt.min, cpt.max
|
1780
|
+
gp.set %{ cbrange [#{min}:#{max}] }
|
1781
|
+
end
|
1782
|
+
gp.put(cpt.to_gnuplot)
|
1783
|
+
end
|
1784
|
+
|
1785
|
+
def self.set_palette_cpt_city (gp, name, opt)
|
1786
|
+
file = File.expand_path(File.join(ENV["CPTCITY"],name) + ".cpt")
|
1787
|
+
cpt = ColorPalette::CPT(file, :continuous=>opt[:continuous])
|
1788
|
+
if opt[:use_scale]
|
1789
|
+
min, max = cpt.min, cpt.max
|
1790
|
+
gp.set %{ cbrange [#{min}:#{max}] }
|
1791
|
+
end
|
1792
|
+
gp.put(cpt.to_gnuplot)
|
1793
|
+
end
|
1794
|
+
|
1795
|
+
def self.set_palette_predefined (gp, name)
|
1796
|
+
case name.to_s
|
1797
|
+
when "gray"
|
1798
|
+
gp.set %{ palette defined (0 "#FFFFFF", \
|
1799
|
+
1 "#000000") }
|
1800
|
+
when "gray_inv"
|
1801
|
+
gp.set %{ palette defined (0 "#000000", \
|
1802
|
+
1 "#FFFFFF") }
|
1803
|
+
when "rainbow"
|
1804
|
+
gp.set %{ palette rgbformulae 22,13,-31 }
|
1805
|
+
when "polar"
|
1806
|
+
gp.set %{ palette defined (-1 "blue", \
|
1807
|
+
0 "white", \
|
1808
|
+
1 "red") }
|
1809
|
+
when "jet"
|
1810
|
+
gp.set %{ palette defined (0 "#00007F", \
|
1811
|
+
0.125 "#0000FF", \
|
1812
|
+
0.375 "#FFFFFF", \
|
1813
|
+
0.625 "#FFFF00", \
|
1814
|
+
0.875 "#FF0000", \
|
1815
|
+
1 "#7F0000") }
|
1816
|
+
when "split"
|
1817
|
+
gp.set %{ palette defined (-1.0 "#7F7FFF", \
|
1818
|
+
-0.5 "#000080", \
|
1819
|
+
0.0 "#000000", \
|
1820
|
+
0.5 "#800000", \
|
1821
|
+
1.0 "#FF7F7F" ) }
|
1822
|
+
when "green_metal"
|
1823
|
+
gp.set %{ palette defined ( 0.0 "#000000", \
|
1824
|
+
0.5263 "#8D8D6C", \
|
1825
|
+
0.6842 "#92BDBE", \
|
1826
|
+
1.0 "#FFFFFF" )}
|
1827
|
+
when "matlab"
|
1828
|
+
gp.set %{ palette defined ( 0 '#000090', \
|
1829
|
+
1 '#000fff', \
|
1830
|
+
2 '#0090ff', \
|
1831
|
+
3 '#0fffee', \
|
1832
|
+
4 '#90ff70', \
|
1833
|
+
5 '#ffee00', \
|
1834
|
+
6 '#ff7000', \
|
1835
|
+
7 '#ee0000', \
|
1836
|
+
8 '#7f0000')}
|
1837
|
+
when "matlabw"
|
1838
|
+
gp.set %{ palette defined ( 0 'white',
|
1839
|
+
0.01 '#000090', \
|
1840
|
+
1 '#000fff', \
|
1841
|
+
2 '#0090ff', \
|
1842
|
+
3 '#0fffee', \
|
1843
|
+
4 '#90ff70', \
|
1844
|
+
5 '#ffee00', \
|
1845
|
+
6 '#ff7000', \
|
1846
|
+
7 '#ee0000', \
|
1847
|
+
8 '#7f0000')}
|
1848
|
+
else
|
1849
|
+
raise "Unknown palette name"
|
1850
|
+
end
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
|
1854
|
+
end
|
1855
|
+
|
1856
|
+
class ColorPalette # :nodoc:
|
1857
|
+
|
1858
|
+
def initialize (model, levels, color, scale = nil, continuous = false)
|
1859
|
+
@model = model
|
1860
|
+
@levels = levels
|
1861
|
+
@color = color
|
1862
|
+
@scale = scale || CArray.int(levels).seq!
|
1863
|
+
@continuous = continuous
|
1864
|
+
end
|
1865
|
+
|
1866
|
+
attr_reader :scale, :colors
|
1867
|
+
|
1868
|
+
def min
|
1869
|
+
return @scale.min
|
1870
|
+
end
|
1871
|
+
|
1872
|
+
def max
|
1873
|
+
return @scale.max
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
def range
|
1877
|
+
return @scale.min..@scale.max
|
1878
|
+
end
|
1879
|
+
|
1880
|
+
def to_gnuplot
|
1881
|
+
out = []
|
1882
|
+
maxcolors = 1024
|
1883
|
+
if @continuous
|
1884
|
+
(@levels).times do |i|
|
1885
|
+
level = @scale[i]
|
1886
|
+
out.push([level, *@color[i,nil].to_a])
|
1887
|
+
end
|
1888
|
+
else
|
1889
|
+
(@levels-1).times do |i|
|
1890
|
+
level = @scale[i]
|
1891
|
+
level1 = @scale[i+1]
|
1892
|
+
out.push([level, *@color[i,nil].to_a])
|
1893
|
+
out.push([level1, *@color[i,nil].to_a])
|
1894
|
+
end
|
1895
|
+
maxcolors = @levels-1
|
1896
|
+
end
|
1897
|
+
return ["set palette model #{@model} maxcolors #{maxcolors} defined (\\",
|
1898
|
+
out.map{|list| " " + list.join(" ")}.join(",\\\n") + "\\",
|
1899
|
+
")"].join("\n")
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
end
|
1903
|
+
|
1904
|
+
class ColorPalette
|
1905
|
+
|
1906
|
+
def self.CPT (file, opt = nil)
|
1907
|
+
options = {:continuous => false}.update(opt)
|
1908
|
+
continuous = options[:continuous]
|
1909
|
+
if File.exist?(file)
|
1910
|
+
text = File.read(file)
|
1911
|
+
else
|
1912
|
+
if continuous
|
1913
|
+
text = IO.popen("makecpt -C#{file} -Z", "r") { |io| io.read }
|
1914
|
+
else
|
1915
|
+
text = IO.popen("makecpt -C#{file}", "r") { |io| io.read }
|
1916
|
+
end
|
1917
|
+
if text =~ /\A\s*\Z/
|
1918
|
+
raise "failed to makecpt #{file}"
|
1919
|
+
end
|
1920
|
+
end
|
1921
|
+
|
1922
|
+
lines = text.split("\n").map{|line| line.strip }
|
1923
|
+
|
1924
|
+
model = "RGB"
|
1925
|
+
entries = []
|
1926
|
+
lines.each do |line|
|
1927
|
+
case line
|
1928
|
+
when /\A\#\s*COLOR_MODEL\s*=\s*\+(.+)\s*\Z/
|
1929
|
+
model = $1.upcase
|
1930
|
+
when /\A\Z/, /\A#/, /\A([FBN])\s*(.*)\Z/
|
1931
|
+
next
|
1932
|
+
else
|
1933
|
+
entries.push(line.split(/\s+/)[0,8].map{|x| x.to_f})
|
1934
|
+
end
|
1935
|
+
end
|
1936
|
+
|
1937
|
+
levels = entries.size * 2
|
1938
|
+
color = CArray.float(levels, 3)
|
1939
|
+
scale = CArray.float(levels)
|
1940
|
+
level = 0
|
1941
|
+
entries.each do |entry|
|
1942
|
+
scale[level] = entry[0]
|
1943
|
+
color[level, nil] = entry[1, 3]
|
1944
|
+
level += 1
|
1945
|
+
scale[level] = entry[4]
|
1946
|
+
color[level, nil] = entry[5, 3]
|
1947
|
+
level += 1
|
1948
|
+
end
|
1949
|
+
|
1950
|
+
if model =~ /HSV/
|
1951
|
+
color[nil, 0] /= 360
|
1952
|
+
else
|
1953
|
+
color[] /= 255
|
1954
|
+
end
|
1955
|
+
|
1956
|
+
return ColorPalette.new(model, levels, color, scale, options[:contiuous])
|
1957
|
+
end
|
1958
|
+
|
1959
|
+
def self.GMT (file, continuous = true)
|
1960
|
+
return CPT(file, :continuous=>continuous)
|
1961
|
+
end
|
1962
|
+
end
|
1963
|
+
|
1964
|
+
end
|
1965
|
+
|
1966
|
+
class ColorPalette < CA::Gnuplot::ColorPalette
|
1967
|
+
end
|
1968
|
+
|
1969
|
+
class CA::Gnuplot
|
1970
|
+
|
1971
|
+
def pi2arc (th0, th1)
|
1972
|
+
return format("%f:%f", -th1+90, -th0+90)
|
1973
|
+
end
|
1974
|
+
|
1975
|
+
def xtics_histogram (ticslabels)
|
1976
|
+
max = ticslabels.size - 1
|
1977
|
+
return -0.5..max+0.5,
|
1978
|
+
(0..max).map{|k|[k,ticslabels[k]]} + (0..max-1).map{|k|[k+0.5,"",1]}
|
1979
|
+
end
|
1980
|
+
|
1981
|
+
def guide_with_x11 (*arg)
|
1982
|
+
@pause_mouse_mode = arg
|
1983
|
+
@pause_mouse_term = "x11"
|
1984
|
+
__guide__
|
1985
|
+
end
|
1986
|
+
|
1987
|
+
def guide_with_wxt (*arg)
|
1988
|
+
@pause_mouse_mode = arg
|
1989
|
+
@pause_mouse_term = "wxt"
|
1990
|
+
__guide__
|
1991
|
+
end
|
1992
|
+
|
1993
|
+
def __guide__
|
1994
|
+
guides = []
|
1995
|
+
@pause_mouse_mode.each do |mode|
|
1996
|
+
guide = ""
|
1997
|
+
if mode.to_s[-1,1] == "!"
|
1998
|
+
confirm = true
|
1999
|
+
mode = mode.to_s[0..-2].intern
|
2000
|
+
else
|
2001
|
+
confirm = false
|
2002
|
+
end
|
2003
|
+
loop do
|
2004
|
+
begin
|
2005
|
+
put %{
|
2006
|
+
set term push
|
2007
|
+
set term #{@pause_mouse_term}
|
2008
|
+
replot
|
2009
|
+
}
|
2010
|
+
case mode
|
2011
|
+
when :click
|
2012
|
+
puts "Wait mouse: 1-mouse click required"
|
2013
|
+
put "pause mouse"
|
2014
|
+
mx = evaluate "MOUSE_X"
|
2015
|
+
my = evaluate "MOUSE_Y"
|
2016
|
+
when :point
|
2017
|
+
puts "Draw point: 1-mouse click required"
|
2018
|
+
put "pause mouse"
|
2019
|
+
mx = evaluate "MOUSE_X"
|
2020
|
+
my = evaluate "MOUSE_Y"
|
2021
|
+
guide = %{set %{ label "" at #{mx},#{my} point }}
|
2022
|
+
set %{ label "" at #{mx},#{my} point pt 7 ps 2 }
|
2023
|
+
put %{ refresh }
|
2024
|
+
when :label, :clabel, :llabel, :rlabel
|
2025
|
+
puts "Draw label: 1-mouse click required"
|
2026
|
+
put "pause mouse"
|
2027
|
+
mx = evaluate "MOUSE_X"
|
2028
|
+
my = evaluate "MOUSE_Y"
|
2029
|
+
print "label text: "
|
2030
|
+
STDOUT.flush
|
2031
|
+
text = STDIN.gets.chomp
|
2032
|
+
case mode
|
2033
|
+
when :label, :llabel
|
2034
|
+
just = "left"
|
2035
|
+
when :clabel
|
2036
|
+
just = "center"
|
2037
|
+
when :rlabel
|
2038
|
+
just = "right"
|
2039
|
+
end
|
2040
|
+
guide = %{set %{ label #{text.dump} at #{"%.5g" % mx},#{"%.5g" %my} #{just} }}
|
2041
|
+
set %{ label #{text.dump} at #{mx},#{my} #{just} }
|
2042
|
+
put %{ refresh }
|
2043
|
+
when :arrow
|
2044
|
+
puts "Draw arrow: finish with right click"
|
2045
|
+
guide = ""
|
2046
|
+
pairs = []
|
2047
|
+
i = 0
|
2048
|
+
loop do
|
2049
|
+
put "pause mouse"
|
2050
|
+
mx = evaluate "MOUSE_X"
|
2051
|
+
my = evaluate "MOUSE_Y"
|
2052
|
+
mb = evaluate "MOUSE_BUTTON"
|
2053
|
+
pairs << [mx, my]
|
2054
|
+
if i >= 1
|
2055
|
+
if i == 1
|
2056
|
+
head = ""
|
2057
|
+
else
|
2058
|
+
head = "nohead"
|
2059
|
+
end
|
2060
|
+
mx1,my1 = pairs[i-1]
|
2061
|
+
mx2,my2 = pairs[i]
|
2062
|
+
guide << %{set %{ arrow from #{"%.5g" % mx2},#{"%.5g" % my2} to #{"%.5g" % mx1},#{"%.5g" % my1} #{head}} } << "\n"
|
2063
|
+
set %{ arrow from #{"%.5g" % mx2},#{"%.5g" % my2} to #{"%.5g" % mx1},#{"%.5g" % my1} #{head}}
|
2064
|
+
put %{ refresh }
|
2065
|
+
end
|
2066
|
+
if mb == "3"
|
2067
|
+
break
|
2068
|
+
end
|
2069
|
+
i += 1
|
2070
|
+
end
|
2071
|
+
when :key
|
2072
|
+
puts "Draw key: 1-mouse click required"
|
2073
|
+
put "pause mouse"
|
2074
|
+
mx = evaluate "MOUSE_X"
|
2075
|
+
my = evaluate "MOUSE_Y"
|
2076
|
+
guide = %{set %{ key at #{"%.5g" % mx},#{"%.5g" % my} }}
|
2077
|
+
set %{ key at #{mx},#{my} }
|
2078
|
+
put %{ refresh }
|
2079
|
+
else
|
2080
|
+
raise "invalid pause_mouse_mode #{@pause_mouse_mode}"
|
2081
|
+
end
|
2082
|
+
terminal %{ pop }
|
2083
|
+
if @output
|
2084
|
+
output @output
|
2085
|
+
end
|
2086
|
+
put %{ replot }
|
2087
|
+
unset %{ output }
|
2088
|
+
if confirm
|
2089
|
+
print "ok? (Y/n) "
|
2090
|
+
STDOUT.flush
|
2091
|
+
begin
|
2092
|
+
curstty = %x{stty -g}
|
2093
|
+
system "stty raw -echo -icanon isig"
|
2094
|
+
c = STDIN.getc;
|
2095
|
+
ensure
|
2096
|
+
system "stty #{curstty}"
|
2097
|
+
end
|
2098
|
+
puts
|
2099
|
+
if c == ?N or c == ?n
|
2100
|
+
raise
|
2101
|
+
end
|
2102
|
+
end
|
2103
|
+
break
|
2104
|
+
rescue
|
2105
|
+
retry
|
2106
|
+
end
|
2107
|
+
end
|
2108
|
+
guides << guide
|
2109
|
+
end
|
2110
|
+
@pause_mouse_mode = nil
|
2111
|
+
puts guides.join("\n")
|
2112
|
+
pause
|
2113
|
+
end
|
2114
|
+
|
2115
|
+
|
2116
|
+
end
|