ruby-gr 0.0.15 → 0.0.20
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.
- checksums.yaml +4 -4
- data/README.md +109 -28
- data/lib/gr.rb +105 -66
- data/lib/gr/ffi.rb +6 -1
- data/lib/gr/grbase.rb +2 -3
- data/lib/gr/plot.rb +251 -202
- data/lib/gr3.rb +51 -40
- data/lib/gr3/gr3base.rb +2 -3
- data/lib/gr_commons/define_methods.rb +2 -2
- data/lib/gr_commons/fiddley.rb +1 -1
- data/lib/gr_commons/gr_common_utils.rb +53 -27
- data/lib/gr_commons/version.rb +1 -1
- data/lib/grm.rb +45 -0
- data/lib/grm/ffi.rb +63 -0
- data/lib/grm/grmbase.rb +13 -0
- data/lib/grm/version.rb +5 -0
- metadata +13 -8
data/lib/gr/ffi.rb
CHANGED
@@ -63,6 +63,7 @@ module GR
|
|
63
63
|
try_extern 'void gr_settextcolorind(int)'
|
64
64
|
try_extern 'void gr_inqtextcolorind(int *)'
|
65
65
|
try_extern 'void gr_setcharheight(double)'
|
66
|
+
try_extern 'void gr_inqcharheight(double *)'
|
66
67
|
try_extern 'void gr_setcharup(double, double)'
|
67
68
|
try_extern 'void gr_settextpath(int)'
|
68
69
|
try_extern 'void gr_settextalign(int, int)'
|
@@ -196,6 +197,10 @@ module GR
|
|
196
197
|
try_extern 'void gr_inqwindow3d(double *, double *, double *, double *, double *, double *)'
|
197
198
|
try_extern 'void gr_setscalefactors3d(double, double, double)'
|
198
199
|
try_extern 'void gr_inqscalefactors3d(double *, double *, double *)'
|
199
|
-
try_extern 'void
|
200
|
+
try_extern 'void gr_setspace3d(double, double, double, double)'
|
201
|
+
try_extern 'void gr_text3d(double, double, double, char *, int axis)'
|
202
|
+
try_extern 'void gr_inqtext3d(double, double, double, char *, int axis, double *, double *)'
|
203
|
+
try_extern 'void gr_settextencoding(int)'
|
204
|
+
try_extern 'void gr_inqtextencoding(int *)'
|
200
205
|
end
|
201
206
|
end
|
data/lib/gr/grbase.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module GR
|
4
|
-
# This module automatically converts Ruby arrays and Numo::Narray into
|
4
|
+
# This module automatically converts Ruby arrays and Numo::Narray into
|
5
|
+
# Fiddley::MemoryPointer.
|
5
6
|
module GRBase
|
6
7
|
extend GRCommons::DefineMethods
|
7
8
|
define_ffi_methods(FFI,
|
@@ -9,6 +10,4 @@ module GR
|
|
9
10
|
default_type: :double)
|
10
11
|
end
|
11
12
|
private_constant :GRBase
|
12
|
-
|
13
|
-
extend GRCommons::GRCommonUtils
|
14
13
|
end
|
data/lib/gr/plot.rb
CHANGED
@@ -37,59 +37,59 @@ module GR
|
|
37
37
|
volume].freeze # the name might be changed in the future.
|
38
38
|
|
39
39
|
# Keyword options conform to GR.jl.
|
40
|
-
KW_ARGS = %i[accelerate algorithm alpha backgroundcolor barwidth baseline
|
41
|
-
clabels color colormap figsize horizontal
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
40
|
+
KW_ARGS = %i[accelerate algorithm alpha ax backgroundcolor barwidth baseline
|
41
|
+
clabels clear clim color colormap crange figsize grid horizontal
|
42
|
+
isovalue kind label labels levels location nbins ratio rotation
|
43
|
+
scale size spec subplot tilt title update xaxis xflip xform
|
44
|
+
xlabel xlim xlog xrange xticks yaxis yflip ylabel ylim ylog
|
45
|
+
zflip yrange yticks viewport vp where window zaxis zlabel zlim
|
46
|
+
zlog zrange zticks].freeze
|
47
|
+
|
48
|
+
@last_plot = nil
|
49
|
+
class << self
|
50
|
+
attr_accessor :last_plot
|
49
51
|
end
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
attr_accessor :args, :kvs, :scheme
|
54
|
+
|
55
|
+
def initialize(*raw_args)
|
56
|
+
@kvs = raw_args.last.is_a?(Hash) ? raw_args.pop : {}
|
57
|
+
@args = plot_args(raw_args) # method name is the same as Julia/Python
|
58
|
+
|
57
59
|
# Check keyword options.
|
58
|
-
|
59
|
-
warn "Unknown keyword: #{k}" unless KW_ARGS.include? k
|
60
|
-
end
|
60
|
+
kvs.each_key { |k| warn "Unknown keyword: #{k}" unless KW_ARGS.include? k }
|
61
61
|
|
62
62
|
# label(singular form) is a original keyword arg which GR.jl does not have.
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
kvs[:labels] ||= [kvs[:label]] if kvs.has_key? :label
|
64
|
+
|
65
|
+
# Don't use || because we need to tell `false` from `nil`
|
66
|
+
kvs[:size] = [600, 450] unless kvs.has_key? :size
|
67
|
+
kvs[:ax] = false unless kvs.has_key? :ax
|
68
|
+
kvs[:subplot] = [0, 1, 0, 1] unless kvs.has_key? :subplot
|
69
|
+
kvs[:clear] = true unless kvs.has_key? :clear
|
70
|
+
kvs[:update] = true unless kvs.has_key? :update
|
71
|
+
|
72
|
+
@scheme = 0
|
72
73
|
@background = 0xffffff
|
73
|
-
@handle
|
74
|
-
|
74
|
+
# @handle = nil # This variable will be used in gr_meta
|
75
|
+
|
76
|
+
self.class.last_plot = self
|
75
77
|
end
|
76
|
-
attr_accessor :args, :kvs, :scheme
|
77
78
|
|
78
79
|
def set_viewport(kind, subplot)
|
79
80
|
mwidth, mheight, width, height = GR.inqdspsize
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
end
|
91
|
-
viewport = [0, 0, 0, 0]
|
81
|
+
dpi = width / mwidth * 0.0254
|
82
|
+
w, h = if kvs[:figsize]
|
83
|
+
[(0.0254 * width * kvs[:figsize][0] / mwidth),
|
84
|
+
(0.0254 * height * kvs[:figsize][1] / mheight)]
|
85
|
+
elsif dpi > 200
|
86
|
+
kvs[:size].map { |i| i * dpi / 100 }
|
87
|
+
else
|
88
|
+
kvs[:size]
|
89
|
+
end
|
90
|
+
|
92
91
|
vp = subplot.clone
|
92
|
+
|
93
93
|
if w > h
|
94
94
|
ratio = h / w.to_f
|
95
95
|
msize = mwidth * w / width
|
@@ -105,6 +105,7 @@ module GR
|
|
105
105
|
vp[0] *= ratio
|
106
106
|
vp[1] *= ratio
|
107
107
|
end
|
108
|
+
|
108
109
|
if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
109
110
|
extent = [vp[1] - vp[0], vp[3] - vp[2]].min
|
110
111
|
vp1 = 0.5 * (vp[0] + vp[1] - extent)
|
@@ -114,10 +115,12 @@ module GR
|
|
114
115
|
else
|
115
116
|
vp1, vp2, vp3, vp4 = vp
|
116
117
|
end
|
117
|
-
|
118
|
-
viewport
|
119
|
-
|
120
|
-
|
118
|
+
|
119
|
+
viewport = [vp1 + 0.125 * (vp2 - vp1),
|
120
|
+
vp1 + 0.925 * (vp2 - vp1),
|
121
|
+
vp3 + 0.125 * (vp4 - vp3),
|
122
|
+
vp3 + 0.925 * (vp4 - vp3)]
|
123
|
+
|
121
124
|
if %i[contour contourf hexbin heatmap nonuniformheatmap polarheatmap
|
122
125
|
surface trisurf volume].include?(kind)
|
123
126
|
viewport[1] -= 0.1
|
@@ -131,11 +134,11 @@ module GR
|
|
131
134
|
end
|
132
135
|
end
|
133
136
|
|
134
|
-
GR.setviewport(viewport
|
137
|
+
GR.setviewport(*viewport)
|
135
138
|
|
136
139
|
kvs[:viewport] = viewport
|
137
|
-
kvs[:vp]
|
138
|
-
kvs[:ratio]
|
140
|
+
kvs[:vp] = vp
|
141
|
+
kvs[:ratio] = ratio
|
139
142
|
|
140
143
|
if kvs[:backgroundcolor]
|
141
144
|
GR.savestate
|
@@ -165,14 +168,15 @@ module GR
|
|
165
168
|
def set_window(kind)
|
166
169
|
scale = 0
|
167
170
|
unless %i[polar polarhist polarheatmap].include?(kind)
|
168
|
-
scale |= GR::OPTION_X_LOG
|
169
|
-
scale |= GR::OPTION_Y_LOG
|
170
|
-
scale |= GR::OPTION_Z_LOG
|
171
|
+
scale |= GR::OPTION_X_LOG if kvs[:xlog]
|
172
|
+
scale |= GR::OPTION_Y_LOG if kvs[:ylog]
|
173
|
+
scale |= GR::OPTION_Z_LOG if kvs[:zlog]
|
171
174
|
scale |= GR::OPTION_FLIP_X if kvs[:xflip]
|
172
175
|
scale |= GR::OPTION_FLIP_Y if kvs[:yflip]
|
173
176
|
scale |= GR::OPTION_FLIP_Z if kvs[:zflip]
|
174
177
|
end
|
175
178
|
kvs[:scale] = scale
|
179
|
+
|
176
180
|
if kvs.has_key?(:panzoom)
|
177
181
|
xmin, xmax, ymin, ymax = GR.panzoom(*kvs[:panzoom])
|
178
182
|
kvs[:xrange] = [xmin, xmax]
|
@@ -181,72 +185,77 @@ module GR
|
|
181
185
|
minmax
|
182
186
|
end
|
183
187
|
|
184
|
-
major_count =
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
188
|
+
major_count = %i[wireframe surface plot3 scatter3 polar polarhist
|
189
|
+
polarheatmap trisurf volume].include?(kind) ? 2 : 5
|
190
|
+
|
191
|
+
kvs[:xticks] = [kvs[:xticks], major_count] if kvs[:xticks].is_a? Numeric
|
192
|
+
kvs[:yticks] = [kvs[:yticks], major_count] if kvs[:yticks].is_a? Numeric
|
193
|
+
kvs[:zticks] = [kvs[:zticks], major_count] if kvs[:zticks].is_a? Numeric
|
190
194
|
|
191
195
|
xmin, xmax = kvs[:xrange]
|
192
|
-
if (
|
193
|
-
xmin
|
194
|
-
|
195
|
-
xtick, majorx = kvs[:xticks]
|
196
|
-
else
|
197
|
-
majorx = major_count
|
198
|
-
xtick = GR.tick(xmin, xmax) / majorx
|
199
|
-
end
|
200
|
-
else
|
201
|
-
xtick = majorx = 1
|
196
|
+
if %i[heatmap polarheatmap].include?(kind) && kvs.has_key?(:xlim)
|
197
|
+
xmin -= 0.5
|
198
|
+
xmax += 0.5
|
202
199
|
end
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
200
|
+
xtick, majorx = if (scale & GR::OPTION_X_LOG) == 0
|
201
|
+
unless %i[heatmap polarheatmap].include?(kind)
|
202
|
+
unless kvs.has_key?(:xlim)
|
203
|
+
xmin, xmax = GR.adjustlimits(xmin, xmax) unless kvs[:panzoom]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
if kvs.has_key?(:xticks)
|
207
|
+
kvs[:xticks]
|
208
|
+
else
|
209
|
+
[GR.tick(xmin, xmax) / major_count, major_count]
|
210
|
+
end
|
211
|
+
else
|
212
|
+
[1, 1]
|
213
|
+
end
|
214
|
+
xorg = (scale & GR::OPTION_FLIP_X) == 0 ? [xmin, xmax] : [xmax, xmin]
|
208
215
|
kvs[:xaxis] = xtick, xorg, majorx
|
209
216
|
|
210
217
|
ymin, ymax = kvs[:yrange]
|
211
|
-
if kind
|
212
|
-
ymin
|
218
|
+
if %i[heatmap polarheatmap].include?(kind) && kvs.has_key?(:ylim)
|
219
|
+
ymin -= 0.5
|
220
|
+
ymax += 0.5
|
213
221
|
end
|
214
|
-
if
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
majory = major_count
|
220
|
-
ytick = GR.tick(ymin, ymax) / majory
|
222
|
+
if kind == :hist
|
223
|
+
if kvs[:horizontal] && !kvs.has_key?(:xlim)
|
224
|
+
xmin = (scale & GR::OPTION_X_LOG) == 0 ? 0 : 1
|
225
|
+
elsif !kvs.has_key?(:ylim)
|
226
|
+
ymin = (scale & GR::OPTION_Y_LOG) == 0 ? 0 : 1
|
221
227
|
end
|
222
|
-
else
|
223
|
-
ytick = majory = 1
|
224
228
|
end
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
229
|
+
ytick, majory = if (scale & GR::OPTION_Y_LOG) == 0
|
230
|
+
unless %i[heatmap polarheatmap].include?(kind)
|
231
|
+
unless kvs.has_key?(:ylim)
|
232
|
+
ymin, ymax = GR.adjustlimits(ymin, ymax) unless kvs[:panzoom]
|
233
|
+
end
|
234
|
+
end
|
235
|
+
if kvs.has_key?(:yticks)
|
236
|
+
kvs[:yticks]
|
237
|
+
else
|
238
|
+
[GR.tick(ymin, ymax) / major_count, major_count]
|
239
|
+
end
|
240
|
+
else
|
241
|
+
[1, 1]
|
242
|
+
end
|
243
|
+
yorg = (scale & GR::OPTION_FLIP_Y) == 0 ? [ymin, ymax] : [ymax, ymin]
|
230
244
|
kvs[:yaxis] = ytick, yorg, majory
|
231
245
|
|
232
246
|
if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
233
247
|
zmin, zmax = kvs[:zrange]
|
234
|
-
if (scale & GR::OPTION_Z_LOG) == 0
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
zorg = if (scale & GR::OPTION_FLIP_Z) == 0
|
246
|
-
[zmin, zmax]
|
247
|
-
else
|
248
|
-
[zmax, zmin]
|
249
|
-
end
|
248
|
+
ztick, majorz = if (scale & GR::OPTION_Z_LOG) == 0
|
249
|
+
zmin, zmax = GR.adjustlimits(zmin, zmax) if kvs.has_key?(:zlim)
|
250
|
+
if kvs.has_key?(:zticks)
|
251
|
+
kvs[:zticks]
|
252
|
+
else
|
253
|
+
[GR.tick(zmin, zmax) / major_count, major_count]
|
254
|
+
end
|
255
|
+
else
|
256
|
+
[1, 1]
|
257
|
+
end
|
258
|
+
zorg = (scale & GR::OPTION_FLIP_Z) == 0 ? [zmin, zmax] : [zmax, zmin]
|
250
259
|
kvs[:zaxis] = ztick, zorg, majorz
|
251
260
|
end
|
252
261
|
|
@@ -258,7 +267,7 @@ module GR
|
|
258
267
|
end
|
259
268
|
if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
260
269
|
rotation = kvs[:rotation] || 40
|
261
|
-
tilt
|
270
|
+
tilt = kvs[:tilt] || 70
|
262
271
|
GR.setspace(zmin, zmax, rotation, tilt)
|
263
272
|
end
|
264
273
|
|
@@ -272,7 +281,7 @@ module GR
|
|
272
281
|
ratio = kvs[:ratio]
|
273
282
|
xtick, xorg, majorx = kvs[:xaxis]
|
274
283
|
ytick, yorg, majory = kvs[:yaxis]
|
275
|
-
drawgrid = kvs[:grid]
|
284
|
+
drawgrid = kvs.has_key?(:grid) ? kvs[:grid] : true
|
276
285
|
xtick = 10 if kvs[:scale] & GR::OPTION_X_LOG != 0
|
277
286
|
ytick = 10 if kvs[:scale] & GR::OPTION_Y_LOG != 0
|
278
287
|
GR.setlinecolorind(1)
|
@@ -293,8 +302,8 @@ module GR
|
|
293
302
|
else
|
294
303
|
if %i[heatmap nonuniformheatmap shade].include?(kind)
|
295
304
|
ticksize = -ticksize
|
296
|
-
|
297
|
-
|
305
|
+
elsif drawgrid
|
306
|
+
GR.grid(xtick, ytick, 0, 0, majorx, majory)
|
298
307
|
end
|
299
308
|
if kvs.has_key?(:xticklabels) || kvs.has_key?(:yticklabels)
|
300
309
|
fx = if kvs.has_key?(:xticklabels)
|
@@ -332,7 +341,7 @@ module GR
|
|
332
341
|
GR.axes(xtick, ytick, xorg[1], yorg[1], -majorx, -majory, -ticksize)
|
333
342
|
end
|
334
343
|
|
335
|
-
if kvs
|
344
|
+
if kvs[:title]
|
336
345
|
GR.savestate
|
337
346
|
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
|
338
347
|
text(0.5 * (viewport[0] + viewport[1]), vp[3], kvs[:title])
|
@@ -421,7 +430,7 @@ module GR
|
|
421
430
|
if img.is_a? String
|
422
431
|
width, height, data = GR.readimage(img)
|
423
432
|
else
|
424
|
-
|
433
|
+
height, width = img.shape
|
425
434
|
cmin, cmax = kvs[:crange]
|
426
435
|
data = img.map { |i| normalize_color(i, cmin, cmax) }
|
427
436
|
data = data.map { |i| (1000 + i * 255).round }
|
@@ -488,7 +497,9 @@ module GR
|
|
488
497
|
end
|
489
498
|
|
490
499
|
GR.selntran(0)
|
491
|
-
|
500
|
+
v = Numo::DFloat.cast(v) if v.is_a? Array
|
501
|
+
values = ((v - v.min) / (v.max - v.min) * (2**16 - 1)).round
|
502
|
+
values = Numo::UInt16.cast(values)
|
492
503
|
nx, ny, nz = v.shape
|
493
504
|
isovalue = ((kvs[:isovalue] || 0.5) - v.min) / (v.max - v.min)
|
494
505
|
rotation = ((kvs[:rotation] || 40) * Math::PI / 180.0)
|
@@ -497,7 +508,7 @@ module GR
|
|
497
508
|
GR3.clear
|
498
509
|
mesh = GR3.createisosurfacemesh(values, [2.0 / (nx - 1), 2.0 / (ny - 1), 2.0 / (nz - 1)],
|
499
510
|
[-1, -1, -1],
|
500
|
-
(isovalue * (2
|
511
|
+
(isovalue * (2**16 - 1)).round)
|
501
512
|
color = kvs[:color] || [0.0, 0.5, 0.8]
|
502
513
|
GR3.setbackgroundcolor(1, 1, 1, 0)
|
503
514
|
GR3.drawmesh(mesh, 1, [0, 0, 0], [0, 0, 1], [0, 1, 0], color, [1, 1, 1])
|
@@ -582,8 +593,7 @@ module GR
|
|
582
593
|
|
583
594
|
GR.uselinespec(' ')
|
584
595
|
args.each do |x, y, z, c, spec|
|
585
|
-
|
586
|
-
spec ||= ''
|
596
|
+
spec ||= kvs[:spec] ||= ''
|
587
597
|
GR.savestate
|
588
598
|
GR.settransparency(kvs[:alpha]) if kvs.has_key?(:alpha)
|
589
599
|
|
@@ -657,14 +667,26 @@ module GR
|
|
657
667
|
GR.polymarker(x, y)
|
658
668
|
|
659
669
|
when :hist
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
670
|
+
if kvs[:horizontal]
|
671
|
+
xmin = kvs[:window][0]
|
672
|
+
x.length.times do |i|
|
673
|
+
GR.setfillcolorind(989)
|
674
|
+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
675
|
+
GR.fillrect(xmin, x[i], y[i], y[i + 1])
|
676
|
+
GR.setfillcolorind(1)
|
677
|
+
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
678
|
+
GR.fillrect(xmin, x[i], y[i], y[i + 1])
|
679
|
+
end
|
680
|
+
else
|
681
|
+
ymin = kvs[:window][2]
|
682
|
+
y.length.times do |i|
|
683
|
+
GR.setfillcolorind(989)
|
684
|
+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
685
|
+
GR.fillrect(x[i], x[i + 1], ymin, y[i])
|
686
|
+
GR.setfillcolorind(1)
|
687
|
+
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
688
|
+
GR.fillrect(x[i], x[i + 1], ymin, y[i])
|
689
|
+
end
|
668
690
|
end
|
669
691
|
|
670
692
|
when :polarhist
|
@@ -685,9 +707,10 @@ module GR
|
|
685
707
|
cmap = colormap
|
686
708
|
cmin, cmax = kvs[:zrange]
|
687
709
|
data = z.map { |i| normalize_color(i, cmin, cmax) }
|
688
|
-
|
689
|
-
|
690
|
-
|
710
|
+
data.reverse(axis: 0) if kvs[:xflip]
|
711
|
+
data.reverse(axis: 1) if kvs[:yflip]
|
712
|
+
colors = data * 255 + 1000
|
713
|
+
colors = colors.transpose # Julia is column major
|
691
714
|
GR.polarcellarray(0, 0, 0, 360, 0, 1, w, h, colors)
|
692
715
|
draw_polar_axes
|
693
716
|
kvs[:zrange] = [cmin, cmax]
|
@@ -699,11 +722,18 @@ module GR
|
|
699
722
|
a, b = z.shape
|
700
723
|
x = (1..b).to_a
|
701
724
|
y = (1..a).to_a
|
702
|
-
zmin, zmax =
|
725
|
+
zmin, zmax = z.minmax
|
703
726
|
elsif equal_length(x, y, z)
|
704
727
|
x, y, z = GR.gridit(x, y, z, 200, 200)
|
705
|
-
zmin, zmax =
|
728
|
+
zmin, zmax = z.compact.minmax # compact : removed nil
|
729
|
+
end
|
730
|
+
|
731
|
+
# kvs[:zlim] is supposed to be Array or Range
|
732
|
+
if kvs.has_key?(:zlim)
|
733
|
+
zmin = kvs[:zlim].first if kvs[:zlim].first
|
734
|
+
zmax = kvs[:zlim].last if kvs[:zlim].last
|
706
735
|
end
|
736
|
+
|
707
737
|
GR.setspace(zmin, zmax, 0, 90)
|
708
738
|
levels = kvs[:levels] || 0
|
709
739
|
clabels = kvs[:clabels] || false
|
@@ -795,7 +825,9 @@ module GR
|
|
795
825
|
colorbar(0.05)
|
796
826
|
|
797
827
|
when :plot3
|
798
|
-
GR.
|
828
|
+
mask = GR.uselinespec(spec)
|
829
|
+
GR.polyline3d(x, y, z) if hasline(mask)
|
830
|
+
GR.polymarker3d(x, y, z) if hasmarker(mask)
|
799
831
|
draw_axes(kind, 2)
|
800
832
|
|
801
833
|
when :scatter3
|
@@ -858,7 +890,7 @@ module GR
|
|
858
890
|
|
859
891
|
draw_legend if %i[line step scatter stem].include?(kind) && kvs.has_key?(:labels)
|
860
892
|
|
861
|
-
if kvs
|
893
|
+
if kvs[:update]
|
862
894
|
GR.updatews
|
863
895
|
# if GR.isinline()
|
864
896
|
# restore_context()
|
@@ -978,24 +1010,31 @@ module GR
|
|
978
1010
|
[*0..(num - 1)].collect { |i| low + i.to_f * (high - low) / (num - 1) }
|
979
1011
|
end
|
980
1012
|
|
981
|
-
def plot_args(args
|
1013
|
+
def plot_args(args)
|
982
1014
|
# FIXME
|
983
1015
|
args = [args] unless args.all? do |i|
|
984
1016
|
i.is_a?(Array) && (i[0].is_a?(Array) || narray?(i[0]))
|
985
1017
|
end
|
986
1018
|
args.map do |xyzc|
|
1019
|
+
spec = nil
|
1020
|
+
case xyzc.last
|
1021
|
+
when String
|
1022
|
+
spec = xyzc.pop
|
1023
|
+
when Hash
|
1024
|
+
spec = xyzc.pop[:spec]
|
1025
|
+
end
|
1026
|
+
|
987
1027
|
x, y, z, c = xyzc.map do |i|
|
988
|
-
if i.is_a?(Array) || narray?(i)
|
1028
|
+
if i.is_a?(Array) || narray?(i) || i.nil?
|
989
1029
|
i
|
990
1030
|
elsif i.respond_to?(:to_a)
|
991
1031
|
# Convert an Array-like class such as Daru::Vector to an Array
|
992
1032
|
i.to_a
|
993
|
-
else
|
994
|
-
# String
|
1033
|
+
else # String
|
995
1034
|
i
|
996
1035
|
end
|
997
1036
|
end
|
998
|
-
[x, y, z, c]
|
1037
|
+
[x, y, z, c, spec]
|
999
1038
|
end
|
1000
1039
|
end
|
1001
1040
|
|
@@ -1042,7 +1081,8 @@ module GR
|
|
1042
1081
|
args.each do |x, y, z, c|
|
1043
1082
|
if x
|
1044
1083
|
if scale & GR::OPTION_X_LOG != 0
|
1045
|
-
|
1084
|
+
# duck typing for NArray
|
1085
|
+
x = x.map { |v| v > 0 ? v : Float::NAN }
|
1046
1086
|
end
|
1047
1087
|
x0, x1 = x.minmax
|
1048
1088
|
xmin = [x0, xmin].min
|
@@ -1053,7 +1093,7 @@ module GR
|
|
1053
1093
|
end
|
1054
1094
|
if y
|
1055
1095
|
if scale & GR::OPTION_Y_LOG != 0
|
1056
|
-
y.map
|
1096
|
+
y = y.map { |v| v > 0 ? v : Float::NAN }
|
1057
1097
|
end
|
1058
1098
|
y0, y1 = y.minmax
|
1059
1099
|
ymin = [y0, ymin].min
|
@@ -1064,7 +1104,7 @@ module GR
|
|
1064
1104
|
end
|
1065
1105
|
if z
|
1066
1106
|
if scale & GR::OPTION_Z_LOG != 0
|
1067
|
-
z.map
|
1107
|
+
z = z.map { |v| v > 0 ? v : Float::NAN }
|
1068
1108
|
end
|
1069
1109
|
z0, z1 = z.minmax
|
1070
1110
|
zmin = [z0, zmin].min
|
@@ -1083,30 +1123,12 @@ module GR
|
|
1083
1123
|
xmin, xmax = fix_minmax(xmin, xmax)
|
1084
1124
|
ymin, ymax = fix_minmax(ymin, ymax)
|
1085
1125
|
zmin, zmax = fix_minmax(zmin, zmax)
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
kvs[:xrange] = [xmin, xmax]
|
1093
|
-
end
|
1094
|
-
if kvs.has_key?(:ylim)
|
1095
|
-
y0, y1 = kvs[:ylim]
|
1096
|
-
y0 ||= ymin
|
1097
|
-
y1 ||= ymax
|
1098
|
-
kvs[:yrange] = [y0, y1]
|
1099
|
-
else
|
1100
|
-
kvs[:yrange] = [ymin, ymax]
|
1101
|
-
end
|
1102
|
-
if kvs.has_key?(:zlim)
|
1103
|
-
z0, z1 = kvs[:zlim]
|
1104
|
-
z0 ||= zmin
|
1105
|
-
z1 ||= zmax
|
1106
|
-
kvs[:zrange] = [z0, z1]
|
1107
|
-
else
|
1108
|
-
kvs[:zrange] = [zmin, zmax]
|
1109
|
-
end
|
1126
|
+
|
1127
|
+
# kvs[:xlim], kvs[:ylim], kvs[:zlim] is supposed to be Array or Range
|
1128
|
+
kvs[:xrange] = [(kvs[:xlim]&.first || xmin), (kvs[:xlim]&.last || xmax)]
|
1129
|
+
kvs[:yrange] = [(kvs[:ylim]&.first || ymin), (kvs[:ylim]&.last || ymax)]
|
1130
|
+
kvs[:zrange] = [(kvs[:zlim]&.first || zmin), (kvs[:zlim]&.last || zmax)]
|
1131
|
+
|
1110
1132
|
if kvs.has_key?(:clim)
|
1111
1133
|
c0, c1 = kvs[:clim]
|
1112
1134
|
c0 ||= cmin
|
@@ -1185,7 +1207,8 @@ module GR
|
|
1185
1207
|
# (Plot) Draw a heatmap.
|
1186
1208
|
def heatmap(*args)
|
1187
1209
|
# FIXME
|
1188
|
-
|
1210
|
+
args, kv = format_xyzc(*args)
|
1211
|
+
_x, _y, z = args
|
1189
1212
|
ysize, xsize = z.shape
|
1190
1213
|
z = z.reshape(xsize, ysize)
|
1191
1214
|
create_plot(:heatmap, kv) do |plt|
|
@@ -1213,15 +1236,13 @@ module GR
|
|
1213
1236
|
alias _contour_ contour
|
1214
1237
|
# (Plot) Draw a contour plot.
|
1215
1238
|
def contour(*args)
|
1216
|
-
|
1217
|
-
create_plot(:contour, x, y, z, kv)
|
1239
|
+
create_plot(:contour, *format_xyzc(*args))
|
1218
1240
|
end
|
1219
1241
|
|
1220
1242
|
alias _contourf_ contourf
|
1221
1243
|
# (Plot) Draw a filled contour plot.
|
1222
1244
|
def contourf(*args)
|
1223
|
-
|
1224
|
-
create_plot(:contourf, x, y, z, kv)
|
1245
|
+
create_plot(:contourf, *format_xyzc(*args))
|
1225
1246
|
end
|
1226
1247
|
|
1227
1248
|
alias _hexbin_ hexbin
|
@@ -1232,21 +1253,18 @@ module GR
|
|
1232
1253
|
|
1233
1254
|
# (Plot) Draw a triangular contour plot.
|
1234
1255
|
def tricont(*args)
|
1235
|
-
|
1236
|
-
create_plot(:tricont, x, y, z, kv)
|
1256
|
+
create_plot(:tricont, *format_xyzc(*args))
|
1237
1257
|
end
|
1238
1258
|
|
1239
1259
|
# (Plot) Draw a three-dimensional wireframe plot.
|
1240
1260
|
def wireframe(*args)
|
1241
|
-
|
1242
|
-
create_plot(:wireframe, x, y, z, kv)
|
1261
|
+
create_plot(:wireframe, *format_xyzc(*args))
|
1243
1262
|
end
|
1244
1263
|
|
1245
1264
|
# (Plot) Draw a three-dimensional surface plot.
|
1246
1265
|
alias _surface_ surface
|
1247
1266
|
def surface(*args)
|
1248
|
-
|
1249
|
-
create_plot(:surface, x, y, z, kv)
|
1267
|
+
create_plot(:surface, *format_xyzc(*args))
|
1250
1268
|
end
|
1251
1269
|
|
1252
1270
|
# (Plot)
|
@@ -1256,8 +1274,7 @@ module GR
|
|
1256
1274
|
|
1257
1275
|
# (Plot) Draw a triangular surface plot.
|
1258
1276
|
def trisurf(*args)
|
1259
|
-
|
1260
|
-
create_plot(:trisurf, x, y, z, kv)
|
1277
|
+
create_plot(:trisurf, *format_xyzc(*args))
|
1261
1278
|
end
|
1262
1279
|
|
1263
1280
|
# (Plot) Draw one or more three-dimensional line plots.
|
@@ -1287,9 +1304,8 @@ module GR
|
|
1287
1304
|
def barplot(labels, heights, kv = {})
|
1288
1305
|
labels = labels.map(&:to_s)
|
1289
1306
|
wc, hc = barcoordinates(heights)
|
1290
|
-
horizontal = kv[:horizontal] || false
|
1291
1307
|
create_plot(:bar, labels, heights, kv) do |plt|
|
1292
|
-
if horizontal
|
1308
|
+
if kv[:horizontal]
|
1293
1309
|
plt.args = [[hc, wc, nil, nil, '']]
|
1294
1310
|
plt.kvs[:yticks] = [1, 1]
|
1295
1311
|
plt.kvs[:yticklabels] = labels
|
@@ -1302,11 +1318,15 @@ module GR
|
|
1302
1318
|
end
|
1303
1319
|
|
1304
1320
|
# (Plot) Draw a histogram.
|
1305
|
-
def histogram(
|
1306
|
-
create_plot(:hist,
|
1321
|
+
def histogram(series, kv = {})
|
1322
|
+
create_plot(:hist, series, kv) do |plt|
|
1307
1323
|
nbins = plt.kvs[:nbins] || 0
|
1308
|
-
x, y = hist(
|
1309
|
-
plt.args = [
|
1324
|
+
x, y = hist(series, nbins)
|
1325
|
+
plt.args = if kv[:horizontal]
|
1326
|
+
[[y, x, nil, nil, '']]
|
1327
|
+
else
|
1328
|
+
[[x, y, nil, nil, '']]
|
1329
|
+
end
|
1310
1330
|
end
|
1311
1331
|
end
|
1312
1332
|
|
@@ -1326,6 +1346,34 @@ module GR
|
|
1326
1346
|
end
|
1327
1347
|
end
|
1328
1348
|
|
1349
|
+
def hold(flag = true)
|
1350
|
+
plt = GR::Plot.last_plot
|
1351
|
+
plt.kvs.slice(:window, :scale, :xaxis, :yaxis, :zaxis).merge({ ax: flag, clear: !flag })
|
1352
|
+
end
|
1353
|
+
|
1354
|
+
# Set current subplot index.
|
1355
|
+
def subplot(nr, nc, p, kv = {})
|
1356
|
+
xmin = 1
|
1357
|
+
xmax = 0
|
1358
|
+
ymin = 1
|
1359
|
+
ymax = 0
|
1360
|
+
p = [p] if p.is_a? Integer
|
1361
|
+
p.each do |i|
|
1362
|
+
r = (nr - (i - 1) / nc).to_f
|
1363
|
+
c = ((i - 1) % nc + 1).to_f
|
1364
|
+
xmin = [xmin, (c - 1) / nc].min
|
1365
|
+
xmax = [xmax, c / nc].max
|
1366
|
+
ymin = [ymin, (r - 1) / nr].min
|
1367
|
+
ymax = [ymax, r / nr].max
|
1368
|
+
end
|
1369
|
+
{
|
1370
|
+
subplot: [xmin, xmax, ymin, ymax],
|
1371
|
+
# The policy of clearing when p[0]==1 is controversial
|
1372
|
+
clear: p[0] == 1,
|
1373
|
+
update: p[-1] == nr * nc
|
1374
|
+
}.merge kv
|
1375
|
+
end
|
1376
|
+
|
1329
1377
|
# (Plot) Save the current figure to a file.
|
1330
1378
|
def savefig(filename, kv = {})
|
1331
1379
|
GR.beginprint(filename)
|
@@ -1337,40 +1385,41 @@ module GR
|
|
1337
1385
|
|
1338
1386
|
private
|
1339
1387
|
|
1340
|
-
def create_plot(type, *args
|
1388
|
+
def create_plot(type, *args)
|
1341
1389
|
plt = GR::Plot.new(*args)
|
1342
1390
|
plt.kvs[:kind] = type
|
1343
|
-
|
1391
|
+
yield(plt) if block_given?
|
1344
1392
|
plt.plot_data
|
1345
1393
|
plt
|
1346
1394
|
end
|
1347
1395
|
|
1348
|
-
def
|
1396
|
+
def format_xyzc(*args)
|
1349
1397
|
kv = if args[-1].is_a? Hash
|
1350
1398
|
args.pop
|
1351
1399
|
else
|
1352
1400
|
{}
|
1353
1401
|
end
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1402
|
+
|
1403
|
+
args = [args] unless args.all? do |i|
|
1404
|
+
i.is_a?(Array) && (i[0].is_a?(Array) || narray?(i[0]))
|
1405
|
+
end
|
1406
|
+
args.map! do |xyzc|
|
1407
|
+
if xyzc.size == 1
|
1408
|
+
if xyzc[0].is_a? Array
|
1409
|
+
z = Numo::DFloat.cast(xyzc[0])
|
1410
|
+
elsif narray?(xyzc[0])
|
1411
|
+
z = xyzc[0]
|
1412
|
+
end
|
1413
|
+
xsize, ysize = z.shape
|
1414
|
+
x = (1..ysize).to_a * xsize
|
1415
|
+
y = (1..xsize).map { |i| Array.new(ysize, i) }.flatten
|
1416
|
+
[x, y, z]
|
1417
|
+
else
|
1418
|
+
|
1419
|
+
xyzc
|
1359
1420
|
end
|
1360
|
-
xsize, ysize = z.shape
|
1361
|
-
# NOTE:
|
1362
|
-
# See
|
1363
|
-
# https://github.com/jheinen/GR.jl/pull/246
|
1364
|
-
# https://github.com/jheinen/GR.jl/issues/241
|
1365
|
-
x = (1..ysize).to_a * xsize
|
1366
|
-
y = (1..xsize).map { |i| Array.new(ysize, i) }.flatten
|
1367
|
-
|
1368
|
-
elsif args.size == 3
|
1369
|
-
x, y, z = args
|
1370
|
-
else
|
1371
|
-
raise
|
1372
1421
|
end
|
1373
|
-
[
|
1422
|
+
[*args, kv]
|
1374
1423
|
end
|
1375
1424
|
|
1376
1425
|
def hist(x, nbins = 0)
|