ruby-gr 0.0.16 → 0.0.21
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 +103 -29
- data/lib/gr.rb +106 -71
- data/lib/gr/ffi.rb +6 -1
- data/lib/gr/plot.rb +179 -154
- data/lib/gr3.rb +41 -44
- data/lib/gr_commons/fiddley.rb +1 -1
- data/lib/gr_commons/gr_commons.rb +4 -0
- data/lib/gr_commons/search_shared_library.rb +31 -0
- data/lib/gr_commons/version.rb +1 -1
- data/lib/grm.rb +52 -0
- data/lib/grm/ffi.rb +73 -0
- data/lib/grm/grmbase.rb +13 -0
- data/lib/grm/version.rb +5 -0
- metadata +28 -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/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
|
-
|
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
|
45
47
|
|
46
48
|
@last_plot = nil
|
47
49
|
class << self
|
48
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 ||= here, 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
|
+
# @handle = nil # This variable will be used in gr_meta
|
75
|
+
|
74
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]
|
@@ -188,65 +192,74 @@ module GR
|
|
188
192
|
5
|
189
193
|
end
|
190
194
|
|
195
|
+
kvs[:xticks] = [kvs[:xticks], major_count] if kvs[:xticks].is_a? Numeric
|
196
|
+
kvs[:yticks] = [kvs[:yticks], major_count] if kvs[:yticks].is_a? Numeric
|
197
|
+
kvs[:zticks] = [kvs[:zticks], major_count] if kvs[:zticks].is_a? Numeric
|
198
|
+
|
191
199
|
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
|
200
|
+
if %i[heatmap polarheatmap].include?(kind) && kvs.has_key?(:xlim)
|
201
|
+
xmin -= 0.5
|
202
|
+
xmax += 0.5
|
202
203
|
end
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
204
|
+
xtick, majorx = if (scale & GR::OPTION_X_LOG) == 0
|
205
|
+
unless %i[heatmap polarheatmap].include?(kind)
|
206
|
+
unless kvs.has_key?(:xlim)
|
207
|
+
xmin, xmax = GR.adjustlimits(xmin, xmax) unless kvs[:panzoom]
|
208
|
+
end
|
209
|
+
end
|
210
|
+
if kvs.has_key?(:xticks)
|
211
|
+
kvs[:xticks]
|
212
|
+
else
|
213
|
+
[GR.tick(xmin, xmax) / major_count, major_count]
|
214
|
+
end
|
215
|
+
else
|
216
|
+
[1, 1]
|
217
|
+
end
|
218
|
+
xorg = (scale & GR::OPTION_FLIP_X) == 0 ? [xmin, xmax] : [xmax, xmin]
|
208
219
|
kvs[:xaxis] = xtick, xorg, majorx
|
209
220
|
|
210
221
|
ymin, ymax = kvs[:yrange]
|
211
|
-
if kind
|
212
|
-
ymin
|
222
|
+
if %i[heatmap polarheatmap].include?(kind) && kvs.has_key?(:ylim)
|
223
|
+
ymin -= 0.5
|
224
|
+
ymax += 0.5
|
213
225
|
end
|
214
|
-
if
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
majory = major_count
|
220
|
-
ytick = GR.tick(ymin, ymax) / majory
|
226
|
+
if kind == :hist
|
227
|
+
if kvs[:horizontal] && !kvs.has_key?(:xlim)
|
228
|
+
xmin = (scale & GR::OPTION_X_LOG) == 0 ? 0 : 1
|
229
|
+
elsif !kvs.has_key?(:ylim)
|
230
|
+
ymin = (scale & GR::OPTION_Y_LOG) == 0 ? 0 : 1
|
221
231
|
end
|
222
|
-
else
|
223
|
-
ytick = majory = 1
|
224
232
|
end
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
233
|
+
ytick, majory = if (scale & GR::OPTION_Y_LOG) == 0
|
234
|
+
unless %i[heatmap polarheatmap].include?(kind)
|
235
|
+
unless kvs.has_key?(:ylim)
|
236
|
+
ymin, ymax = GR.adjustlimits(ymin, ymax) unless kvs[:panzoom]
|
237
|
+
end
|
238
|
+
end
|
239
|
+
if kvs.has_key?(:yticks)
|
240
|
+
kvs[:yticks]
|
241
|
+
else
|
242
|
+
[GR.tick(ymin, ymax) / major_count, major_count]
|
243
|
+
end
|
244
|
+
else
|
245
|
+
[1, 1]
|
246
|
+
end
|
247
|
+
yorg = (scale & GR::OPTION_FLIP_Y) == 0 ? [ymin, ymax] : [ymax, ymin]
|
230
248
|
kvs[:yaxis] = ytick, yorg, majory
|
231
249
|
|
232
250
|
if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
233
251
|
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
|
252
|
+
ztick, majorz = if (scale & GR::OPTION_Z_LOG) == 0
|
253
|
+
zmin, zmax = GR.adjustlimits(zmin, zmax) if kvs.has_key?(:zlim)
|
254
|
+
if kvs.has_key?(:zticks)
|
255
|
+
kvs[:zticks]
|
256
|
+
else
|
257
|
+
[GR.tick(zmin, zmax) / major_count, major_count]
|
258
|
+
end
|
259
|
+
else
|
260
|
+
[1, 1]
|
261
|
+
end
|
262
|
+
zorg = (scale & GR::OPTION_FLIP_Z) == 0 ? [zmin, zmax] : [zmax, zmin]
|
250
263
|
kvs[:zaxis] = ztick, zorg, majorz
|
251
264
|
end
|
252
265
|
|
@@ -258,7 +271,7 @@ module GR
|
|
258
271
|
end
|
259
272
|
if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
260
273
|
rotation = kvs[:rotation] || 40
|
261
|
-
tilt
|
274
|
+
tilt = kvs[:tilt] || 70
|
262
275
|
GR.setspace(zmin, zmax, rotation, tilt)
|
263
276
|
end
|
264
277
|
|
@@ -272,7 +285,7 @@ module GR
|
|
272
285
|
ratio = kvs[:ratio]
|
273
286
|
xtick, xorg, majorx = kvs[:xaxis]
|
274
287
|
ytick, yorg, majory = kvs[:yaxis]
|
275
|
-
drawgrid = kvs[:grid]
|
288
|
+
drawgrid = kvs.has_key?(:grid) ? kvs[:grid] : true
|
276
289
|
xtick = 10 if kvs[:scale] & GR::OPTION_X_LOG != 0
|
277
290
|
ytick = 10 if kvs[:scale] & GR::OPTION_Y_LOG != 0
|
278
291
|
GR.setlinecolorind(1)
|
@@ -293,8 +306,8 @@ module GR
|
|
293
306
|
else
|
294
307
|
if %i[heatmap nonuniformheatmap shade].include?(kind)
|
295
308
|
ticksize = -ticksize
|
296
|
-
|
297
|
-
|
309
|
+
elsif drawgrid
|
310
|
+
GR.grid(xtick, ytick, 0, 0, majorx, majory)
|
298
311
|
end
|
299
312
|
if kvs.has_key?(:xticklabels) || kvs.has_key?(:yticklabels)
|
300
313
|
fx = if kvs.has_key?(:xticklabels)
|
@@ -332,7 +345,7 @@ module GR
|
|
332
345
|
GR.axes(xtick, ytick, xorg[1], yorg[1], -majorx, -majory, -ticksize)
|
333
346
|
end
|
334
347
|
|
335
|
-
if kvs
|
348
|
+
if kvs[:title]
|
336
349
|
GR.savestate
|
337
350
|
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
|
338
351
|
text(0.5 * (viewport[0] + viewport[1]), vp[3], kvs[:title])
|
@@ -421,7 +434,7 @@ module GR
|
|
421
434
|
if img.is_a? String
|
422
435
|
width, height, data = GR.readimage(img)
|
423
436
|
else
|
424
|
-
|
437
|
+
height, width = img.shape
|
425
438
|
cmin, cmax = kvs[:crange]
|
426
439
|
data = img.map { |i| normalize_color(i, cmin, cmax) }
|
427
440
|
data = data.map { |i| (1000 + i * 255).round }
|
@@ -488,7 +501,9 @@ module GR
|
|
488
501
|
end
|
489
502
|
|
490
503
|
GR.selntran(0)
|
491
|
-
|
504
|
+
v = Numo::DFloat.cast(v) if v.is_a? Array
|
505
|
+
values = ((v - v.min) / (v.max - v.min) * (2**16 - 1)).round
|
506
|
+
values = Numo::UInt16.cast(values)
|
492
507
|
nx, ny, nz = v.shape
|
493
508
|
isovalue = ((kvs[:isovalue] || 0.5) - v.min) / (v.max - v.min)
|
494
509
|
rotation = ((kvs[:rotation] || 40) * Math::PI / 180.0)
|
@@ -497,7 +512,7 @@ module GR
|
|
497
512
|
GR3.clear
|
498
513
|
mesh = GR3.createisosurfacemesh(values, [2.0 / (nx - 1), 2.0 / (ny - 1), 2.0 / (nz - 1)],
|
499
514
|
[-1, -1, -1],
|
500
|
-
(isovalue * (2
|
515
|
+
(isovalue * (2**16 - 1)).round)
|
501
516
|
color = kvs[:color] || [0.0, 0.5, 0.8]
|
502
517
|
GR3.setbackgroundcolor(1, 1, 1, 0)
|
503
518
|
GR3.drawmesh(mesh, 1, [0, 0, 0], [0, 0, 1], [0, 1, 0], color, [1, 1, 1])
|
@@ -562,7 +577,9 @@ module GR
|
|
562
577
|
# Not yet.
|
563
578
|
end
|
564
579
|
|
565
|
-
GR.
|
580
|
+
# The following fonts are the default in GR.jl
|
581
|
+
# Japanese, Chinese, Korean, etc. cannot be displayed.
|
582
|
+
# GR.settextfontprec(232, 3) # CM Serif Roman
|
566
583
|
|
567
584
|
set_viewport(kind, kvs[:subplot])
|
568
585
|
unless kvs[:ax]
|
@@ -630,8 +647,7 @@ module GR
|
|
630
647
|
if z || c
|
631
648
|
if c
|
632
649
|
cmin, cmax = kvs[:crange]
|
633
|
-
c = c.
|
634
|
-
c.map! { |i| normalize_color(i, cmin, cmax) }
|
650
|
+
c = c.map { |i| normalize_color(i, cmin, cmax) }
|
635
651
|
cind = c.map { |i| (1000 + i * 255).round }
|
636
652
|
end
|
637
653
|
x.length.times do |i|
|
@@ -656,14 +672,26 @@ module GR
|
|
656
672
|
GR.polymarker(x, y)
|
657
673
|
|
658
674
|
when :hist
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
675
|
+
if kvs[:horizontal]
|
676
|
+
xmin = kvs[:window][0]
|
677
|
+
x.length.times do |i|
|
678
|
+
GR.setfillcolorind(989)
|
679
|
+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
680
|
+
GR.fillrect(xmin, x[i], y[i], y[i + 1])
|
681
|
+
GR.setfillcolorind(1)
|
682
|
+
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
683
|
+
GR.fillrect(xmin, x[i], y[i], y[i + 1])
|
684
|
+
end
|
685
|
+
else
|
686
|
+
ymin = kvs[:window][2]
|
687
|
+
y.length.times do |i|
|
688
|
+
GR.setfillcolorind(989)
|
689
|
+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
690
|
+
GR.fillrect(x[i], x[i + 1], ymin, y[i])
|
691
|
+
GR.setfillcolorind(1)
|
692
|
+
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
693
|
+
GR.fillrect(x[i], x[i + 1], ymin, y[i])
|
694
|
+
end
|
667
695
|
end
|
668
696
|
|
669
697
|
when :polarhist
|
@@ -684,9 +712,10 @@ module GR
|
|
684
712
|
cmap = colormap
|
685
713
|
cmin, cmax = kvs[:zrange]
|
686
714
|
data = z.map { |i| normalize_color(i, cmin, cmax) }
|
687
|
-
|
688
|
-
|
689
|
-
|
715
|
+
data.reverse(axis: 0) if kvs[:xflip]
|
716
|
+
data.reverse(axis: 1) if kvs[:yflip]
|
717
|
+
colors = data * 255 + 1000
|
718
|
+
colors = colors.transpose # Julia is column major
|
690
719
|
GR.polarcellarray(0, 0, 0, 360, 0, 1, w, h, colors)
|
691
720
|
draw_polar_axes
|
692
721
|
kvs[:zrange] = [cmin, cmax]
|
@@ -698,11 +727,18 @@ module GR
|
|
698
727
|
a, b = z.shape
|
699
728
|
x = (1..b).to_a
|
700
729
|
y = (1..a).to_a
|
701
|
-
zmin, zmax =
|
730
|
+
zmin, zmax = z.minmax
|
702
731
|
elsif equal_length(x, y, z)
|
703
732
|
x, y, z = GR.gridit(x, y, z, 200, 200)
|
704
|
-
zmin, zmax =
|
733
|
+
zmin, zmax = z.compact.minmax # compact : removed nil
|
734
|
+
end
|
735
|
+
|
736
|
+
# kvs[:zlim] is supposed to be Array or Range
|
737
|
+
if kvs.has_key?(:zlim)
|
738
|
+
zmin = kvs[:zlim].first if kvs[:zlim].first
|
739
|
+
zmax = kvs[:zlim].last if kvs[:zlim].last
|
705
740
|
end
|
741
|
+
|
706
742
|
GR.setspace(zmin, zmax, 0, 90)
|
707
743
|
levels = kvs[:levels] || 0
|
708
744
|
clabels = kvs[:clabels] || false
|
@@ -803,7 +839,7 @@ module GR
|
|
803
839
|
GR.setmarkertype(GR::MARKERTYPE_SOLID_CIRCLE)
|
804
840
|
if c
|
805
841
|
cmin, cmax = kvs[:crange]
|
806
|
-
c = c.map { |i| normalize_color(i, cmin, cmax) }
|
842
|
+
c = c.map { |i| normalize_color(i, cmin, cmax) }
|
807
843
|
cind = c.map { |i| (1000 + i * 255).round }
|
808
844
|
x.length.times do |i|
|
809
845
|
GR.setmarkercolorind(cind[i])
|
@@ -1009,7 +1045,9 @@ module GR
|
|
1009
1045
|
|
1010
1046
|
# Normalize a color c with the range [cmin, cmax]
|
1011
1047
|
# 0 <= normalize_color(c, cmin, cmax) <= 1
|
1048
|
+
# Note: narray.map{|i| normalize_color(i)} There's room for speedup.
|
1012
1049
|
def normalize_color(c, cmin, cmax)
|
1050
|
+
c = c.to_f # if c is Integer
|
1013
1051
|
c = c.clamp(cmin, cmax) - cmin
|
1014
1052
|
c /= (cmax - cmin) if cmin != cmax
|
1015
1053
|
c
|
@@ -1050,7 +1088,8 @@ module GR
|
|
1050
1088
|
args.each do |x, y, z, c|
|
1051
1089
|
if x
|
1052
1090
|
if scale & GR::OPTION_X_LOG != 0
|
1053
|
-
|
1091
|
+
# duck typing for NArray
|
1092
|
+
x = x.map { |v| v > 0 ? v : Float::NAN }
|
1054
1093
|
end
|
1055
1094
|
x0, x1 = x.minmax
|
1056
1095
|
xmin = [x0, xmin].min
|
@@ -1061,7 +1100,7 @@ module GR
|
|
1061
1100
|
end
|
1062
1101
|
if y
|
1063
1102
|
if scale & GR::OPTION_Y_LOG != 0
|
1064
|
-
y.map
|
1103
|
+
y = y.map { |v| v > 0 ? v : Float::NAN }
|
1065
1104
|
end
|
1066
1105
|
y0, y1 = y.minmax
|
1067
1106
|
ymin = [y0, ymin].min
|
@@ -1072,7 +1111,7 @@ module GR
|
|
1072
1111
|
end
|
1073
1112
|
if z
|
1074
1113
|
if scale & GR::OPTION_Z_LOG != 0
|
1075
|
-
z.map
|
1114
|
+
z = z.map { |v| v > 0 ? v : Float::NAN }
|
1076
1115
|
end
|
1077
1116
|
z0, z1 = z.minmax
|
1078
1117
|
zmin = [z0, zmin].min
|
@@ -1091,30 +1130,12 @@ module GR
|
|
1091
1130
|
xmin, xmax = fix_minmax(xmin, xmax)
|
1092
1131
|
ymin, ymax = fix_minmax(ymin, ymax)
|
1093
1132
|
zmin, zmax = fix_minmax(zmin, zmax)
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
kvs[:xrange] = [xmin, xmax]
|
1101
|
-
end
|
1102
|
-
if kvs.has_key?(:ylim)
|
1103
|
-
y0, y1 = kvs[:ylim]
|
1104
|
-
y0 ||= ymin
|
1105
|
-
y1 ||= ymax
|
1106
|
-
kvs[:yrange] = [y0, y1]
|
1107
|
-
else
|
1108
|
-
kvs[:yrange] = [ymin, ymax]
|
1109
|
-
end
|
1110
|
-
if kvs.has_key?(:zlim)
|
1111
|
-
z0, z1 = kvs[:zlim]
|
1112
|
-
z0 ||= zmin
|
1113
|
-
z1 ||= zmax
|
1114
|
-
kvs[:zrange] = [z0, z1]
|
1115
|
-
else
|
1116
|
-
kvs[:zrange] = [zmin, zmax]
|
1117
|
-
end
|
1133
|
+
|
1134
|
+
# kvs[:xlim], kvs[:ylim], kvs[:zlim] is supposed to be Array or Range
|
1135
|
+
kvs[:xrange] = [(kvs[:xlim]&.first || xmin), (kvs[:xlim]&.last || xmax)]
|
1136
|
+
kvs[:yrange] = [(kvs[:ylim]&.first || ymin), (kvs[:ylim]&.last || ymax)]
|
1137
|
+
kvs[:zrange] = [(kvs[:zlim]&.first || zmin), (kvs[:zlim]&.last || zmax)]
|
1138
|
+
|
1118
1139
|
if kvs.has_key?(:clim)
|
1119
1140
|
c0, c1 = kvs[:clim]
|
1120
1141
|
c0 ||= cmin
|
@@ -1290,9 +1311,8 @@ module GR
|
|
1290
1311
|
def barplot(labels, heights, kv = {})
|
1291
1312
|
labels = labels.map(&:to_s)
|
1292
1313
|
wc, hc = barcoordinates(heights)
|
1293
|
-
horizontal = kv[:horizontal] || false
|
1294
1314
|
create_plot(:bar, labels, heights, kv) do |plt|
|
1295
|
-
if horizontal
|
1315
|
+
if kv[:horizontal]
|
1296
1316
|
plt.args = [[hc, wc, nil, nil, '']]
|
1297
1317
|
plt.kvs[:yticks] = [1, 1]
|
1298
1318
|
plt.kvs[:yticklabels] = labels
|
@@ -1305,11 +1325,15 @@ module GR
|
|
1305
1325
|
end
|
1306
1326
|
|
1307
1327
|
# (Plot) Draw a histogram.
|
1308
|
-
def histogram(
|
1309
|
-
create_plot(:hist,
|
1328
|
+
def histogram(series, kv = {})
|
1329
|
+
create_plot(:hist, series, kv) do |plt|
|
1310
1330
|
nbins = plt.kvs[:nbins] || 0
|
1311
|
-
x, y = hist(
|
1312
|
-
plt.args = [
|
1331
|
+
x, y = hist(series, nbins)
|
1332
|
+
plt.args = if kv[:horizontal]
|
1333
|
+
[[y, x, nil, nil, '']]
|
1334
|
+
else
|
1335
|
+
[[x, y, nil, nil, '']]
|
1336
|
+
end
|
1313
1337
|
end
|
1314
1338
|
end
|
1315
1339
|
|
@@ -1335,7 +1359,7 @@ module GR
|
|
1335
1359
|
end
|
1336
1360
|
|
1337
1361
|
# Set current subplot index.
|
1338
|
-
def subplot(nr, nc, p)
|
1362
|
+
def subplot(nr, nc, p, kv = {})
|
1339
1363
|
xmin = 1
|
1340
1364
|
xmax = 0
|
1341
1365
|
ymin = 1
|
@@ -1351,9 +1375,10 @@ module GR
|
|
1351
1375
|
end
|
1352
1376
|
{
|
1353
1377
|
subplot: [xmin, xmax, ymin, ymax],
|
1378
|
+
# The policy of clearing when p[0]==1 is controversial
|
1354
1379
|
clear: p[0] == 1,
|
1355
1380
|
update: p[-1] == nr * nc
|
1356
|
-
}
|
1381
|
+
}.merge kv
|
1357
1382
|
end
|
1358
1383
|
|
1359
1384
|
# (Plot) Save the current figure to a file.
|