ruby-gr 0.0.16 → 0.0.21
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|