gr-plot 0.0.1 → 0.0.2
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 +24 -0
- data/lib/gr/plot/histogram.rb +34 -0
- data/lib/gr/plot/version.rb +1 -1
- data/lib/gr/plot.rb +619 -280
- metadata +5 -7
data/lib/gr/plot.rb
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'gr'
|
|
4
|
+
require_relative 'plot/version'
|
|
4
5
|
autoload :GR3, 'gr3'
|
|
5
6
|
|
|
6
7
|
# FIXME: Plot should not depend on Numo::Narrray unless the GR3 module is required.
|
|
7
8
|
# Note: The Plot class has a linspace function that is independent of Numo..
|
|
8
9
|
require 'numo/narray'
|
|
10
|
+
require_relative 'plot/histogram'
|
|
9
11
|
|
|
10
12
|
module GR
|
|
11
13
|
# This class offers a simple, matlab-style API built on top of the GR package.
|
|
@@ -31,19 +33,106 @@ module GR
|
|
|
31
33
|
# https://github.com/SciRuby/rubyplot
|
|
32
34
|
|
|
33
35
|
# Plot kinds conform to GR.jl
|
|
34
|
-
PLOT_KIND = %i[
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
PLOT_KIND = %i[
|
|
37
|
+
line
|
|
38
|
+
step
|
|
39
|
+
stairs
|
|
40
|
+
scatter
|
|
41
|
+
stem
|
|
42
|
+
bar
|
|
43
|
+
hist
|
|
44
|
+
contour
|
|
45
|
+
contourf
|
|
46
|
+
hexbin
|
|
47
|
+
heatmap
|
|
48
|
+
nonuniformheatmap
|
|
49
|
+
wireframe
|
|
50
|
+
surface
|
|
51
|
+
plot3
|
|
52
|
+
scatter3
|
|
53
|
+
imshow
|
|
54
|
+
isosurface
|
|
55
|
+
polar
|
|
56
|
+
polarhist
|
|
57
|
+
polarheatmap
|
|
58
|
+
nonuniformpolarheatmap
|
|
59
|
+
trisurf
|
|
60
|
+
tricont
|
|
61
|
+
shade
|
|
62
|
+
volume
|
|
63
|
+
].freeze
|
|
38
64
|
|
|
39
65
|
# Keyword options conform to GR.jl.
|
|
40
|
-
KW_ARGS = %i[
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
66
|
+
KW_ARGS = %i[
|
|
67
|
+
accelerate
|
|
68
|
+
algorithm
|
|
69
|
+
alpha
|
|
70
|
+
ax
|
|
71
|
+
backgroundcolor
|
|
72
|
+
barwidth
|
|
73
|
+
baseline
|
|
74
|
+
borderwidth
|
|
75
|
+
clabels
|
|
76
|
+
clines
|
|
77
|
+
clear
|
|
78
|
+
clim
|
|
79
|
+
color
|
|
80
|
+
colormap
|
|
81
|
+
crange
|
|
82
|
+
dpi
|
|
83
|
+
figsize
|
|
84
|
+
font
|
|
85
|
+
grid
|
|
86
|
+
horizontal
|
|
87
|
+
isovalue
|
|
88
|
+
keepaspect
|
|
89
|
+
kind
|
|
90
|
+
label
|
|
91
|
+
labels
|
|
92
|
+
levels
|
|
93
|
+
linewidth
|
|
94
|
+
location
|
|
95
|
+
markersize
|
|
96
|
+
nbins
|
|
97
|
+
panzoom
|
|
98
|
+
ratio
|
|
99
|
+
rotation
|
|
100
|
+
scale
|
|
101
|
+
size
|
|
102
|
+
spec
|
|
103
|
+
subplot
|
|
104
|
+
theta_direction
|
|
105
|
+
theta_zero_location
|
|
106
|
+
tilt
|
|
107
|
+
title
|
|
108
|
+
update
|
|
109
|
+
viewport
|
|
110
|
+
vp
|
|
111
|
+
where
|
|
112
|
+
window
|
|
113
|
+
xaxis
|
|
114
|
+
xflip
|
|
115
|
+
xform
|
|
116
|
+
xlabel
|
|
117
|
+
xlim
|
|
118
|
+
xlog
|
|
119
|
+
xrange
|
|
120
|
+
xticks
|
|
121
|
+
yaxis
|
|
122
|
+
yflip
|
|
123
|
+
ylabel
|
|
124
|
+
ylim
|
|
125
|
+
ylog
|
|
126
|
+
yrange
|
|
127
|
+
yticks
|
|
128
|
+
zaxis
|
|
129
|
+
zflip
|
|
130
|
+
zlabel
|
|
131
|
+
zlim
|
|
132
|
+
zlog
|
|
133
|
+
zrange
|
|
134
|
+
zticks
|
|
135
|
+
].freeze
|
|
47
136
|
|
|
48
137
|
FONTS = {
|
|
49
138
|
times_roman: 101,
|
|
@@ -78,12 +167,37 @@ module GR
|
|
|
78
167
|
zapfchancery_mediumitalic: 130,
|
|
79
168
|
zapfdingbats: 131,
|
|
80
169
|
cmuserif_math: 232, # original: cmuserif-math
|
|
81
|
-
dejavusans: 233
|
|
170
|
+
dejavusans: 233,
|
|
171
|
+
stix_two_math: 234
|
|
82
172
|
}.freeze
|
|
83
173
|
|
|
174
|
+
THETA_ZERO_LOCATION = {
|
|
175
|
+
'E' => 0,
|
|
176
|
+
'N' => Math::PI / 2,
|
|
177
|
+
'W' => Math::PI,
|
|
178
|
+
'S' => 1.5 * Math::PI
|
|
179
|
+
}.freeze
|
|
180
|
+
|
|
181
|
+
COLORS = [
|
|
182
|
+
[0xffffff, 0x000000, 0xff0000, 0x00ff00, 0x0000ff, 0x00ffff, 0xffff00, 0xff00ff],
|
|
183
|
+
[0x282c34, 0xd7dae0, 0xcb4e42, 0x99c27c, 0x85a9fc, 0x5ab6c1, 0xd09a6a, 0xc57bdb],
|
|
184
|
+
[0xfdf6e3, 0x657b83, 0xdc322f, 0x859900, 0x268bd2, 0x2aa198, 0xb58900, 0xd33682],
|
|
185
|
+
[0x002b36, 0x839496, 0xdc322f, 0x859900, 0x268bd2, 0x2aa198, 0xb58900, 0xd33682]
|
|
186
|
+
].freeze
|
|
187
|
+
|
|
188
|
+
DISTINCT_CMAP = [0, 1, 984, 987, 989, 983, 994, 988].freeze
|
|
189
|
+
|
|
84
190
|
@last_plot = nil
|
|
191
|
+
@scheme = 0
|
|
192
|
+
|
|
85
193
|
class << self
|
|
86
|
-
attr_accessor :last_plot
|
|
194
|
+
attr_accessor :last_plot, :scheme
|
|
195
|
+
|
|
196
|
+
def usecolorscheme(index)
|
|
197
|
+
raise 'Invalid color scheme' unless index >= 1 && index <= 4
|
|
198
|
+
|
|
199
|
+
@scheme = index
|
|
200
|
+
end
|
|
87
201
|
end
|
|
88
202
|
|
|
89
203
|
attr_accessor :args, :kvs, :scheme
|
|
@@ -106,7 +220,7 @@ module GR
|
|
|
106
220
|
kvs[:clear] = true unless kvs.has_key? :clear
|
|
107
221
|
kvs[:update] = true unless kvs.has_key? :update
|
|
108
222
|
|
|
109
|
-
@scheme =
|
|
223
|
+
@scheme = self.class.scheme
|
|
110
224
|
@background = 0xffffff
|
|
111
225
|
# @handle = nil # This variable will be used in gr_meta
|
|
112
226
|
|
|
@@ -115,32 +229,38 @@ module GR
|
|
|
115
229
|
|
|
116
230
|
def set_viewport(kind, subplot)
|
|
117
231
|
mwidth, mheight, width, height = GR.inqdspsize
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
232
|
+
if kvs.has_key?(:figsize)
|
|
233
|
+
w, h = kvs[:figsize]
|
|
234
|
+
if w < 2 && h < 2
|
|
235
|
+
w = width * w / mwidth
|
|
236
|
+
h = height * h / mheight
|
|
237
|
+
end
|
|
238
|
+
else
|
|
239
|
+
dpi = kvs[:dpi]
|
|
240
|
+
dpi ||= (width / mwidth * 0.0254).round
|
|
241
|
+
if dpi > 200
|
|
242
|
+
w, h = kvs[:size].map { |i| i * dpi / 100.0 }
|
|
243
|
+
else
|
|
244
|
+
w, h = kvs[:size]
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
vp = subplot.clone.map(&:to_f)
|
|
129
249
|
|
|
130
250
|
if w > h
|
|
131
|
-
ratio =
|
|
251
|
+
ratio = w / h.to_f
|
|
132
252
|
msize = mwidth * w / width
|
|
133
|
-
GR.setwsviewport(0, msize, 0, msize
|
|
134
|
-
GR.setwswindow(0, 1, 0, ratio)
|
|
135
|
-
vp[2]
|
|
136
|
-
vp[3]
|
|
253
|
+
GR.setwsviewport(0, msize, 0, msize / ratio)
|
|
254
|
+
GR.setwswindow(0, 1, 0, 1 / ratio)
|
|
255
|
+
vp[2] /= ratio
|
|
256
|
+
vp[3] /= ratio
|
|
137
257
|
else
|
|
138
|
-
ratio =
|
|
258
|
+
ratio = h / w.to_f
|
|
139
259
|
msize = mheight * h / height
|
|
140
|
-
GR.setwsviewport(0, msize
|
|
141
|
-
GR.setwswindow(0, ratio, 0, 1)
|
|
142
|
-
vp[0]
|
|
143
|
-
vp[1]
|
|
260
|
+
GR.setwsviewport(0, msize / ratio, 0, msize)
|
|
261
|
+
GR.setwswindow(0, 1 / ratio, 0, 1)
|
|
262
|
+
vp[0] /= ratio
|
|
263
|
+
vp[1] /= ratio
|
|
144
264
|
end
|
|
145
265
|
|
|
146
266
|
if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
|
@@ -154,7 +274,7 @@ module GR
|
|
|
154
274
|
end
|
|
155
275
|
|
|
156
276
|
left_margin = kvs.has_key?(:ylabel) ? 0.05 : 0
|
|
157
|
-
right_margin = if %i[contour contourf hexbin heatmap nonuniformheatmap polarheatmap
|
|
277
|
+
right_margin = if %i[contour contourf tricont hexbin heatmap nonuniformheatmap polarheatmap
|
|
158
278
|
nonuniformpolarheatmap surface trisurf volume].include?(kind)
|
|
159
279
|
(vp2 - vp1) * 0.1
|
|
160
280
|
else
|
|
@@ -171,9 +291,24 @@ module GR
|
|
|
171
291
|
if %i[line step scatter stem].include?(kind) && kvs[:labels]
|
|
172
292
|
location = kvs[:location] || 1
|
|
173
293
|
if [11, 12, 13].include?(location)
|
|
174
|
-
|
|
175
|
-
viewport[1] -=
|
|
294
|
+
w_legend, _h_legend = legend_size
|
|
295
|
+
viewport[1] -= w_legend + 0.1
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
if %i[polar polarhist polarheatmap nonuniformpolarheatmap].include?(kind)
|
|
300
|
+
xmin, xmax, ymin, ymax = viewport
|
|
301
|
+
xcenter = 0.5 * (xmin + xmax)
|
|
302
|
+
ycenter = 0.5 * (ymin + ymax)
|
|
303
|
+
r = 0.45 * [xmax - xmin, ymax - ymin].min
|
|
304
|
+
if kvs.has_key?(:title)
|
|
305
|
+
r *= 0.975
|
|
306
|
+
ycenter -= 0.025 * r
|
|
176
307
|
end
|
|
308
|
+
viewport[0] = xcenter - r
|
|
309
|
+
viewport[1] = xcenter + r
|
|
310
|
+
viewport[2] = ycenter - r
|
|
311
|
+
viewport[3] = ycenter + r
|
|
177
312
|
end
|
|
178
313
|
|
|
179
314
|
GR.setviewport(*viewport)
|
|
@@ -182,29 +317,21 @@ module GR
|
|
|
182
317
|
kvs[:vp] = vp
|
|
183
318
|
kvs[:ratio] = ratio
|
|
184
319
|
|
|
185
|
-
|
|
186
|
-
GR.savestate
|
|
187
|
-
GR.selntran(0)
|
|
188
|
-
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
|
189
|
-
GR.setfillcolorind(kvs[:backgroundcolor])
|
|
190
|
-
if w > h
|
|
191
|
-
GR.fillrect(subplot[0], subplot[1],
|
|
192
|
-
ratio * subplot[2], ratio * subplot[3])
|
|
193
|
-
else
|
|
194
|
-
GR.fillrect(ratio * subplot[0], ratio * subplot[1],
|
|
195
|
-
subplot[2], subplot[3])
|
|
196
|
-
end
|
|
197
|
-
GR.selntran(1)
|
|
198
|
-
GR.restorestate
|
|
199
|
-
end
|
|
320
|
+
return unless kvs[:backgroundcolor]
|
|
200
321
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
GR.
|
|
322
|
+
GR.savestate
|
|
323
|
+
GR.selntran(0)
|
|
324
|
+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
|
325
|
+
GR.setfillcolorind(kvs[:backgroundcolor])
|
|
326
|
+
if w > h
|
|
327
|
+
GR.fillrect(subplot[0], subplot[1],
|
|
328
|
+
ratio * subplot[2], ratio * subplot[3])
|
|
329
|
+
else
|
|
330
|
+
GR.fillrect(ratio * subplot[0], ratio * subplot[1],
|
|
331
|
+
subplot[2], subplot[3])
|
|
207
332
|
end
|
|
333
|
+
GR.selntran(1)
|
|
334
|
+
GR.restorestate
|
|
208
335
|
end
|
|
209
336
|
|
|
210
337
|
def set_window(kind)
|
|
@@ -239,14 +366,13 @@ module GR
|
|
|
239
366
|
kvs[:zticks] = [kvs[:zticks], major_count] if kvs[:zticks].is_a? Numeric
|
|
240
367
|
|
|
241
368
|
xmin, xmax = kvs[:xrange]
|
|
242
|
-
if
|
|
369
|
+
if kind == :heatmap && !kvs.has_key?(:xlim)
|
|
243
370
|
xmin -= 0.5
|
|
244
371
|
xmax += 0.5
|
|
245
372
|
end
|
|
246
373
|
xtick, majorx = if (scale & GR::OPTION_X_LOG) == 0
|
|
247
|
-
if
|
|
248
|
-
|
|
249
|
-
!kvs[:panzoom]
|
|
374
|
+
if !kvs.has_key?(:xlim) && !kvs[:panzoom] &&
|
|
375
|
+
!%i[heatmap polarheatmap nonuniformpolarheatmap].include?(kind)
|
|
250
376
|
xmin, xmax = GR.adjustlimits(xmin, xmax)
|
|
251
377
|
end
|
|
252
378
|
if kvs.has_key?(:xticks)
|
|
@@ -261,21 +387,16 @@ module GR
|
|
|
261
387
|
kvs[:xaxis] = xtick, xorg, majorx
|
|
262
388
|
|
|
263
389
|
ymin, ymax = kvs[:yrange]
|
|
264
|
-
if
|
|
390
|
+
if kind == :heatmap && !kvs.has_key?(:ylim)
|
|
265
391
|
ymin -= 0.5
|
|
266
392
|
ymax += 0.5
|
|
267
393
|
end
|
|
268
|
-
if kind == :hist
|
|
269
|
-
|
|
270
|
-
xmin = (scale & GR::OPTION_X_LOG) == 0 ? 0 : 1
|
|
271
|
-
elsif !kvs.has_key?(:ylim)
|
|
272
|
-
ymin = (scale & GR::OPTION_Y_LOG) == 0 ? 0 : 1
|
|
273
|
-
end
|
|
394
|
+
if kind == :hist && !kvs.has_key?(:ylim)
|
|
395
|
+
ymin = (scale & GR::OPTION_Y_LOG) == 0 ? 0 : 1
|
|
274
396
|
end
|
|
275
397
|
ytick, majory = if (scale & GR::OPTION_Y_LOG) == 0
|
|
276
|
-
if
|
|
277
|
-
|
|
278
|
-
!kvs[:panzoom]
|
|
398
|
+
if !kvs.has_key?(:ylim) && !kvs[:panzoom] &&
|
|
399
|
+
!%i[heatmap polarheatmap nonuniformpolarheatmap].include?(kind)
|
|
279
400
|
ymin, ymax = GR.adjustlimits(ymin, ymax)
|
|
280
401
|
end
|
|
281
402
|
if kvs.has_key?(:yticks)
|
|
@@ -292,7 +413,7 @@ module GR
|
|
|
292
413
|
if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
|
293
414
|
zmin, zmax = kvs[:zrange]
|
|
294
415
|
ztick, majorz = if (scale & GR::OPTION_Z_LOG) == 0
|
|
295
|
-
zmin, zmax = GR.adjustlimits(zmin, zmax)
|
|
416
|
+
zmin, zmax = GR.adjustlimits(zmin, zmax) unless kvs.has_key?(:zlim)
|
|
296
417
|
if kvs.has_key?(:zticks)
|
|
297
418
|
kvs[:zticks]
|
|
298
419
|
else
|
|
@@ -306,10 +427,12 @@ module GR
|
|
|
306
427
|
end
|
|
307
428
|
|
|
308
429
|
kvs[:window] = xmin, xmax, ymin, ymax
|
|
309
|
-
if %i[polar polarhist polarheatmap nonuniformpolarheatmap
|
|
430
|
+
if %i[polar polarhist polarheatmap nonuniformpolarheatmap].include?(kind)
|
|
310
431
|
GR.setwindow(-1, 1, -1, 1)
|
|
432
|
+
GR.setclipregion(GR::REGION_ELLIPSE)
|
|
311
433
|
else
|
|
312
434
|
GR.setwindow(xmin, xmax, ymin, ymax)
|
|
435
|
+
GR.setclipregion(GR::REGION_RECTANGLE)
|
|
313
436
|
end
|
|
314
437
|
if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
|
315
438
|
rotation = kvs[:rotation] || 40
|
|
@@ -325,7 +448,6 @@ module GR
|
|
|
325
448
|
def draw_axes(kind, pass = 1)
|
|
326
449
|
viewport = kvs[:viewport]
|
|
327
450
|
vp = kvs[:vp]
|
|
328
|
-
_ratio = kvs[:ratio]
|
|
329
451
|
xtick, xorg, majorx = kvs[:xaxis]
|
|
330
452
|
ytick, yorg, majory = kvs[:yaxis]
|
|
331
453
|
drawgrid = kvs.has_key?(:grid) ? kvs[:grid] : true
|
|
@@ -339,27 +461,61 @@ module GR
|
|
|
339
461
|
charheight = [0.024 * diag, 0.012].max
|
|
340
462
|
GR.setcharheight(charheight)
|
|
341
463
|
ztick, zorg, majorz = kvs[:zaxis]
|
|
464
|
+
rotation = kvs[:rotation] || 40
|
|
465
|
+
tilt = kvs[:tilt] || 60
|
|
466
|
+
zi = tilt >= 0 && tilt <= 90 ? 0 : 1 # Julia: 1-based index -> Ruby: 0-based index
|
|
467
|
+
xlabel = (kvs[:xlabel] || '').to_s
|
|
468
|
+
ylabel = (kvs[:ylabel] || '').to_s
|
|
469
|
+
zlabel = (kvs[:zlabel] || '').to_s
|
|
470
|
+
GR.setcharheight(charheight * 1.5)
|
|
471
|
+
GR.settitles3d(xlabel, ylabel, zlabel)
|
|
472
|
+
GR.setcharheight(charheight)
|
|
342
473
|
if pass == 1 && drawgrid
|
|
343
|
-
|
|
344
|
-
|
|
474
|
+
if rotation >= 0 && rotation < 90
|
|
475
|
+
GR.grid3d(xtick, 0, ztick, xorg[0], yorg[1], zorg[zi], 2, 0, 2)
|
|
476
|
+
GR.grid3d(0, ytick, 0, xorg[0], yorg[1], zorg[zi], 0, 2, 0)
|
|
477
|
+
elsif rotation >= 90 && rotation < 180
|
|
478
|
+
GR.grid3d(xtick, 0, ztick, xorg[1], yorg[1], zorg[zi], 2, 0, 2)
|
|
479
|
+
GR.grid3d(0, ytick, 0, xorg[1], yorg[1], zorg[zi], 0, 2, 0)
|
|
480
|
+
elsif rotation >= 180 && rotation < 270
|
|
481
|
+
GR.grid3d(xtick, 0, ztick, xorg[1], yorg[0], zorg[zi], 2, 0, 2)
|
|
482
|
+
GR.grid3d(0, ytick, 0, xorg[1], yorg[0], zorg[zi], 0, 2, 0)
|
|
483
|
+
else
|
|
484
|
+
GR.grid3d(xtick, 0, ztick, xorg[0], yorg[0], zorg[0], 2, 0, 2)
|
|
485
|
+
GR.grid3d(0, ytick, 0, xorg[0], yorg[0], zorg[zi], 0, 2, 0)
|
|
486
|
+
end
|
|
487
|
+
elsif rotation >= 0 && rotation < 90
|
|
488
|
+
GR.axes3d(xtick, 0, ztick, xorg[0], yorg[0], zorg[zi], majorx, 0, majorz, -ticksize)
|
|
489
|
+
GR.axes3d(0, ytick, 0, xorg[1], yorg[0], zorg[zi], 0, majory, 0, ticksize)
|
|
490
|
+
elsif rotation >= 90 && rotation < 180
|
|
491
|
+
GR.axes3d(0, 0, ztick, xorg[0], yorg[1], zorg[zi], 0, 0, majorz, -ticksize)
|
|
492
|
+
GR.axes3d(xtick, ytick, 0, xorg[0], yorg[0], zorg[zi], majorx, majory, 0, -ticksize)
|
|
493
|
+
elsif rotation >= 180 && rotation < 270
|
|
494
|
+
GR.axes3d(xtick, 0, ztick, xorg[1], yorg[1], zorg[zi], majorx, 0, majorz, ticksize)
|
|
495
|
+
GR.axes3d(0, ytick, 0, xorg[0], yorg[0], zorg[zi], 0, majory, 0, -ticksize)
|
|
345
496
|
else
|
|
346
|
-
GR.axes3d(
|
|
347
|
-
GR.axes3d(
|
|
497
|
+
GR.axes3d(0, 0, ztick, xorg[1], yorg[0], zorg[zi], 0, 0, majorz, -ticksize)
|
|
498
|
+
GR.axes3d(xtick, ytick, 0, xorg[1], yorg[1], zorg[zi], majorx, majory, 0, ticksize)
|
|
348
499
|
end
|
|
349
500
|
else
|
|
350
501
|
charheight = [0.018 * diag, 0.012].max
|
|
351
502
|
GR.setcharheight(charheight)
|
|
352
|
-
if %i[heatmap nonuniformheatmap shade].include?(kind)
|
|
503
|
+
if %i[heatmap nonuniformheatmap shade contourf].include?(kind)
|
|
353
504
|
ticksize = -ticksize
|
|
354
|
-
|
|
355
|
-
GR.grid(xtick, ytick, 0, 0, majorx, majory)
|
|
505
|
+
drawgrid = false if kind == :shade
|
|
356
506
|
end
|
|
357
507
|
if kvs.has_key?(:xticklabels) || kvs.has_key?(:yticklabels)
|
|
508
|
+
GR.grid(xtick, ytick, 0, 0, majorx, majory) if drawgrid
|
|
358
509
|
fx = if kvs.has_key?(:xticklabels)
|
|
359
510
|
GRCommons::Fiddley::Function.new(
|
|
360
511
|
:void, %i[double double string double]
|
|
361
512
|
) do |x, y, _svalue, value|
|
|
362
|
-
|
|
513
|
+
idx = value.round - 1
|
|
514
|
+
label = if idx >= 0 && idx < kvs[:xticklabels].size
|
|
515
|
+
kvs[:xticklabels][idx]
|
|
516
|
+
else
|
|
517
|
+
''
|
|
518
|
+
end
|
|
363
519
|
GR.textext(x, y, label)
|
|
364
520
|
end
|
|
365
521
|
else
|
|
@@ -373,7 +529,12 @@ module GR
|
|
|
373
529
|
GRCommons::Fiddley::Function.new(
|
|
374
530
|
:void, %i[double double string double]
|
|
375
531
|
) do |x, y, _svalue, value|
|
|
376
|
-
|
|
532
|
+
idx = value.round - 1
|
|
533
|
+
label = if idx >= 0 && idx < kvs[:yticklabels].size
|
|
534
|
+
kvs[:yticklabels][idx]
|
|
535
|
+
else
|
|
536
|
+
''
|
|
537
|
+
end
|
|
377
538
|
GR.textext(x, y, label)
|
|
378
539
|
end
|
|
379
540
|
else
|
|
@@ -385,9 +546,12 @@ module GR
|
|
|
385
546
|
end
|
|
386
547
|
GR.axeslbl(xtick, ytick, xorg[0], yorg[0], majorx, majory, ticksize, fx, fy)
|
|
387
548
|
else
|
|
388
|
-
GR.
|
|
549
|
+
x_axis = GR.axis('X', tick: xtick, org: xorg[0], major_count: majorx, tick_size: ticksize)
|
|
550
|
+
y_axis = GR.axis('Y', tick: ytick, org: yorg[0], major_count: majory, tick_size: ticksize)
|
|
551
|
+
options = GR::AXES_SIMPLE_AXES | GR::AXES_TWIN_AXES
|
|
552
|
+
options |= GR::AXES_WITH_GRID if drawgrid
|
|
553
|
+
GR.drawaxes(x_axis, y_axis, options)
|
|
389
554
|
end
|
|
390
|
-
GR.axes(xtick, ytick, xorg[1], yorg[1], -majorx, -majory, -ticksize)
|
|
391
555
|
end
|
|
392
556
|
|
|
393
557
|
if kvs.has_key?(:title)
|
|
@@ -396,30 +560,26 @@ module GR
|
|
|
396
560
|
text(0.5 * (viewport[0] + viewport[1]), vp[3], kvs[:title].to_s)
|
|
397
561
|
GR.restorestate
|
|
398
562
|
end
|
|
399
|
-
if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
GR.
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
GR.savestate
|
|
407
|
-
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_BOTTOM)
|
|
408
|
-
text(0.5 * (viewport[0] + viewport[1]), vp[2] + 0.5 * charheight, kvs[:xlabel].to_s)
|
|
409
|
-
GR.restorestate
|
|
410
|
-
end
|
|
411
|
-
if kvs.has_key?(:ylabel)
|
|
412
|
-
GR.savestate
|
|
413
|
-
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
|
|
414
|
-
GR.setcharup(-1, 0)
|
|
415
|
-
text(vp[0] + 0.5 * charheight, 0.5 * (viewport[2] + viewport[3]), kvs[:ylabel].to_s)
|
|
416
|
-
GR.restorestate
|
|
417
|
-
end
|
|
563
|
+
return if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
|
|
564
|
+
|
|
565
|
+
if kvs.has_key?(:xlabel)
|
|
566
|
+
GR.savestate
|
|
567
|
+
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_BOTTOM)
|
|
568
|
+
text(0.5 * (viewport[0] + viewport[1]), vp[2] + 0.5 * charheight, kvs[:xlabel].to_s)
|
|
569
|
+
GR.restorestate
|
|
418
570
|
end
|
|
571
|
+
return unless kvs.has_key?(:ylabel)
|
|
572
|
+
|
|
573
|
+
GR.savestate
|
|
574
|
+
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
|
|
575
|
+
GR.setcharup(-1, 0)
|
|
576
|
+
text(vp[0] + 0.5 * charheight, 0.5 * (viewport[2] + viewport[3]), kvs[:ylabel].to_s)
|
|
577
|
+
GR.restorestate
|
|
419
578
|
end
|
|
420
579
|
|
|
421
|
-
def draw_polar_axes
|
|
580
|
+
def draw_polar_axes(pass = 1)
|
|
422
581
|
viewport = kvs[:viewport]
|
|
582
|
+
vp = kvs[:vp]
|
|
423
583
|
diag = Math.sqrt((viewport[1] - viewport[0])**2 + (viewport[3] - viewport[2])**2)
|
|
424
584
|
charheight = [0.018 * diag, 0.012].max
|
|
425
585
|
|
|
@@ -432,41 +592,82 @@ module GR
|
|
|
432
592
|
GR.setlinetype(GR::LINETYPE_SOLID)
|
|
433
593
|
|
|
434
594
|
tick = auto_tick(rmin, rmax)
|
|
435
|
-
n = ((rmax - rmin) / tick
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
595
|
+
n = ((rmax - rmin) / tick).truncate
|
|
596
|
+
if n <= 4
|
|
597
|
+
tick /= 2.0
|
|
598
|
+
n *= 2
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
if pass == 1
|
|
602
|
+
GR.selntran(1)
|
|
603
|
+
(n + 1).times do |i|
|
|
604
|
+
r = i.to_f * tick / (rmax - rmin)
|
|
605
|
+
if r > 0 && r < 1
|
|
606
|
+
if i.even?
|
|
607
|
+
GR.setlinecolorind(88)
|
|
608
|
+
GR.drawarc(-r, r, -r, r, 0, 360)
|
|
609
|
+
else
|
|
610
|
+
GR.setlinecolorind(90)
|
|
611
|
+
GR.drawarc(-r, r, -r, r, 0, 360)
|
|
612
|
+
end
|
|
613
|
+
end
|
|
614
|
+
end
|
|
615
|
+
GR.setclip(0)
|
|
616
|
+
GR.setlinecolorind(88)
|
|
617
|
+
GR.drawarc(-1, 1, -1, 1, 0, 360)
|
|
618
|
+
|
|
619
|
+
GR.setclip(1)
|
|
620
|
+
sign = (kvs[:theta_direction] || 1) > 0 ? 1 : -1
|
|
621
|
+
offs = THETA_ZERO_LOCATION[kvs[:theta_zero_location] || 'E']
|
|
622
|
+
0.step(by: 45, to: 315) do |alpha|
|
|
623
|
+
sinf = Math.sin((alpha * sign) * Math::PI / 180 + offs)
|
|
624
|
+
cosf = Math.cos((alpha * sign) * Math::PI / 180 + offs)
|
|
439
625
|
GR.setlinecolorind(88)
|
|
440
|
-
GR.
|
|
626
|
+
GR.polyline([cosf, 0], [sinf, 0])
|
|
627
|
+
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_HALF)
|
|
628
|
+
x, y = GR.wctondc(1.1 * cosf, 1.1 * sinf)
|
|
629
|
+
GR.textext(x, y, "#{alpha}^o")
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
if kvs.has_key?(:title)
|
|
633
|
+
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
|
|
634
|
+
text(0.5 * (viewport[0] + viewport[1]), vp[3] - 0.02, kvs[:title].to_s)
|
|
635
|
+
end
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
if pass == 2
|
|
639
|
+
start = (rmin / tick).floor.truncate
|
|
640
|
+
(n + 1).times do |i|
|
|
641
|
+
j = start + i
|
|
642
|
+
next unless j * tick >= rmin
|
|
643
|
+
|
|
644
|
+
r = i.to_f * tick / (rmax - rmin)
|
|
645
|
+
next unless i.even?
|
|
646
|
+
|
|
441
647
|
GR.settextalign(GR::TEXT_HALIGN_LEFT, GR::TEXT_VALIGN_HALF)
|
|
442
648
|
x, y = GR.wctondc(0.05, r)
|
|
443
|
-
GR.
|
|
444
|
-
|
|
445
|
-
GR.
|
|
446
|
-
GR.drawarc(-r, r, -r, r, 0, 359)
|
|
649
|
+
fmt = GR.getformat(start, rmin, rmax, tick, 2)
|
|
650
|
+
s = GR.ftoa(j * tick, fmt)
|
|
651
|
+
GR.text(x, y, s)
|
|
447
652
|
end
|
|
448
653
|
end
|
|
449
|
-
|
|
450
|
-
sinf = Math.sin(alpha * Math::PI / 180)
|
|
451
|
-
cosf = Math.cos(alpha * Math::PI / 180)
|
|
452
|
-
GR.polyline([cosf, 0], [sinf, 0])
|
|
453
|
-
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_HALF)
|
|
454
|
-
x, y = GR.wctondc(1.1 * cosf, 1.1 * sinf)
|
|
455
|
-
GR.textext(x, y, "#{alpha}^o")
|
|
456
|
-
end
|
|
654
|
+
|
|
457
655
|
GR.restorestate
|
|
458
656
|
end
|
|
459
657
|
|
|
460
658
|
def plot_polar(θ, ρ)
|
|
461
659
|
window = kvs[:window]
|
|
462
|
-
|
|
463
|
-
|
|
660
|
+
rmin = window[2]
|
|
661
|
+
rmax = window[3]
|
|
662
|
+
sign = (kvs[:theta_direction] || 1) > 0 ? 1 : -1
|
|
663
|
+
offs = THETA_ZERO_LOCATION[kvs[:theta_zero_location] || 'E']
|
|
664
|
+
ρ = ρ.map { |i| (i - rmin) / (rmax - rmin) }
|
|
464
665
|
n = ρ.length
|
|
465
666
|
x = []
|
|
466
667
|
y = []
|
|
467
668
|
n.times do |i|
|
|
468
|
-
x << ρ[i] * Math.cos(θ[i])
|
|
469
|
-
y << ρ[i] * Math.sin(θ[i])
|
|
669
|
+
x << ρ[i] * Math.cos(θ[i] * sign + offs)
|
|
670
|
+
y << ρ[i] * Math.sin(θ[i] * sign + offs)
|
|
470
671
|
end
|
|
471
672
|
GR.polyline(x, y)
|
|
472
673
|
end
|
|
@@ -479,10 +680,21 @@ module GR
|
|
|
479
680
|
if img.is_a? String
|
|
480
681
|
width, height, data = GR.readimage(img)
|
|
481
682
|
else
|
|
482
|
-
|
|
683
|
+
if narray?(img)
|
|
684
|
+
height, width = img.shape
|
|
685
|
+
data = img
|
|
686
|
+
else
|
|
687
|
+
height = img.length
|
|
688
|
+
width = img[0].length
|
|
689
|
+
data = img.flatten
|
|
690
|
+
end
|
|
483
691
|
cmin, cmax = kvs[:crange]
|
|
484
|
-
|
|
485
|
-
|
|
692
|
+
if narray?(data)
|
|
693
|
+
data = (data - cmin) / (cmax - cmin)
|
|
694
|
+
data = (data * 255 + 1000).round.cast_to(Numo::Int32)
|
|
695
|
+
else
|
|
696
|
+
data = data.map { |i| (1000 + normalize_color(i, cmin, cmax) * 255).round }
|
|
697
|
+
end
|
|
486
698
|
end
|
|
487
699
|
|
|
488
700
|
if width * (viewport[3] - viewport[2]) < height * (viewport[1] - viewport[0])
|
|
@@ -501,12 +713,12 @@ module GR
|
|
|
501
713
|
|
|
502
714
|
GR.selntran(0)
|
|
503
715
|
GR.setscale(0)
|
|
504
|
-
if kvs
|
|
716
|
+
if kvs[:xflip]
|
|
505
717
|
tmp = xmax
|
|
506
718
|
xmax = xmin
|
|
507
719
|
xmin = tmp
|
|
508
720
|
end
|
|
509
|
-
if kvs
|
|
721
|
+
if kvs[:yflip]
|
|
510
722
|
tmp = ymax
|
|
511
723
|
ymax = ymin
|
|
512
724
|
ymin = tmp
|
|
@@ -552,8 +764,9 @@ module GR
|
|
|
552
764
|
nx, ny, nz = v.shape
|
|
553
765
|
isovalue = ((kvs[:isovalue] || 0.5) - v.min) / (v.max - v.min)
|
|
554
766
|
rotation = ((kvs[:rotation] || 40) * Math::PI / 180.0)
|
|
555
|
-
tilt = ((kvs[:tilt] ||
|
|
767
|
+
tilt = ((kvs[:tilt] || 60) * Math::PI / 180.0)
|
|
556
768
|
r = 2.5
|
|
769
|
+
require 'gr3'
|
|
557
770
|
GR3.clear
|
|
558
771
|
mesh = GR3.createisosurfacemesh(values, [2.0 / (nx - 1), 2.0 / (ny - 1), 2.0 / (nz - 1)],
|
|
559
772
|
[-1, -1, -1],
|
|
@@ -582,11 +795,12 @@ module GR
|
|
|
582
795
|
GR.inqscale
|
|
583
796
|
end
|
|
584
797
|
GR.setscale(options & mask)
|
|
585
|
-
h = 0.5 * (zmax - zmin) / (colors - 1)
|
|
798
|
+
h = 0 # 0.5 * (zmax - zmin) / (colors - 1)
|
|
586
799
|
GR.setwindow(0, 1, zmin, zmax)
|
|
800
|
+
GR.setclipregion(GR::REGION_RECTANGLE)
|
|
587
801
|
GR.setviewport(viewport[1] + 0.02 + off, viewport[1] + 0.05 + off,
|
|
588
802
|
viewport[2], viewport[3])
|
|
589
|
-
l = linspace(
|
|
803
|
+
l = linspace(0, 1, colors).map { |i| (1000 + i * 255).round }
|
|
590
804
|
GR.cellarray(0, 1, zmax + h, zmin - h, 1, colors, l)
|
|
591
805
|
GR.setlinecolorind(1)
|
|
592
806
|
diag = Math.sqrt((viewport[1] - viewport[0])**2 + (viewport[3] - viewport[2])**2)
|
|
@@ -594,14 +808,24 @@ module GR
|
|
|
594
808
|
GR.setcharheight(charheight)
|
|
595
809
|
if kvs[:scale] & GR::OPTION_Z_LOG == 0
|
|
596
810
|
ztick = auto_tick(zmin, zmax)
|
|
597
|
-
GR.
|
|
811
|
+
y_axis = GR.axis('Y', position: 1, tick: ztick, org: zmin, major_count: 1, tick_size: 0.005)
|
|
812
|
+
GR.drawaxis('Y', y_axis)
|
|
598
813
|
else
|
|
599
814
|
GR.setscale(GR::OPTION_Y_LOG)
|
|
600
|
-
GR.
|
|
815
|
+
y_axis = GR.axis('Y', position: 1, tick: 2, org: zmin, major_count: 1, tick_size: 0.005)
|
|
816
|
+
GR.drawaxis('Y', y_axis)
|
|
601
817
|
end
|
|
602
818
|
GR.restorestate
|
|
603
819
|
end
|
|
604
820
|
|
|
821
|
+
def rgb(color)
|
|
822
|
+
[
|
|
823
|
+
((color >> 16) & 0xff) / 255.0,
|
|
824
|
+
((color >> 8) & 0xff) / 255.0,
|
|
825
|
+
(color & 0xff) / 255.0
|
|
826
|
+
]
|
|
827
|
+
end
|
|
828
|
+
|
|
605
829
|
def plot_data(_figure = true)
|
|
606
830
|
# GR.init
|
|
607
831
|
|
|
@@ -619,7 +843,23 @@ module GR
|
|
|
619
843
|
GR.clearws if kvs[:clear]
|
|
620
844
|
|
|
621
845
|
if scheme != 0
|
|
622
|
-
|
|
846
|
+
8.times do |colorind|
|
|
847
|
+
color = COLORS[scheme - 1][colorind]
|
|
848
|
+
r, g, b = rgb(color)
|
|
849
|
+
GR.setcolorrep(colorind, r, g, b)
|
|
850
|
+
GR.setcolorrep(DISTINCT_CMAP[colorind], r, g, b) if scheme != 1
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
r, g, b = rgb(COLORS[scheme - 1][0])
|
|
854
|
+
r2, g2, b2 = rgb(COLORS[scheme - 1][1])
|
|
855
|
+
rdiff = r2 - r
|
|
856
|
+
gdiff = g2 - g
|
|
857
|
+
bdiff = b2 - b
|
|
858
|
+
|
|
859
|
+
12.times do |colorind|
|
|
860
|
+
f = colorind / 11.0
|
|
861
|
+
GR.setcolorrep(91 - colorind, r + f * rdiff, g + f * gdiff, b + f * bdiff)
|
|
862
|
+
end
|
|
623
863
|
end
|
|
624
864
|
|
|
625
865
|
if kvs.has_key?(:font)
|
|
@@ -670,14 +910,26 @@ module GR
|
|
|
670
910
|
|
|
671
911
|
when :line
|
|
672
912
|
mask = GR.uselinespec(spec)
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
913
|
+
if c
|
|
914
|
+
linewidth = kvs[:linewidth] || 1
|
|
915
|
+
z = Array.new(x.length, linewidth)
|
|
916
|
+
GR.polyline(x, y, z, c)
|
|
917
|
+
else
|
|
918
|
+
if hasline(mask)
|
|
919
|
+
linewidth = kvs[:linewidth] || 1
|
|
920
|
+
GR.setlinewidth(linewidth)
|
|
921
|
+
GR.polyline(x, y)
|
|
922
|
+
end
|
|
923
|
+
if hasmarker(mask)
|
|
924
|
+
markersize = kvs[:markersize] || 1
|
|
925
|
+
GR.setmarkersize(markersize)
|
|
926
|
+
borderwidth = kvs[:borderwidth] || 1
|
|
927
|
+
GR.setborderwidth(borderwidth)
|
|
928
|
+
GR.polymarker(x, y)
|
|
929
|
+
end
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
when :step, :stairs
|
|
681
933
|
mask = GR.uselinespec(spec)
|
|
682
934
|
if hasline(mask)
|
|
683
935
|
where = kvs[:where] || 'mid'
|
|
@@ -711,43 +963,48 @@ module GR
|
|
|
711
963
|
|
|
712
964
|
when :scatter
|
|
713
965
|
GR.setmarkertype(GR::MARKERTYPE_SOLID_CIRCLE)
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
966
|
+
if z || c
|
|
967
|
+
if c
|
|
968
|
+
cmin, cmax = kvs[:crange]
|
|
969
|
+
c = c.map { |i| normalize_color(i, cmin, cmax) }
|
|
970
|
+
c = c.map { |i| (1000 + i * 255).round }
|
|
971
|
+
end
|
|
972
|
+
GR.polymarker(x, y, z, c)
|
|
973
|
+
else
|
|
974
|
+
GR.polymarker(x, y)
|
|
975
|
+
end
|
|
717
976
|
|
|
718
977
|
when :stem
|
|
719
|
-
GR.setlinecolorind(1)
|
|
720
|
-
GR.polyline(kvs[:window][0..1], [0, 0])
|
|
721
978
|
GR.setmarkertype(GR::MARKERTYPE_SOLID_CIRCLE)
|
|
722
979
|
GR.uselinespec(spec)
|
|
723
980
|
x = x.to_a if narray?(x)
|
|
724
981
|
y = y.to_a if narray?(y)
|
|
725
982
|
x.zip(y).each do |xi, yi|
|
|
726
983
|
GR.polyline([xi, xi], [0, yi])
|
|
984
|
+
GR.polymarker([xi], [yi])
|
|
985
|
+
end
|
|
986
|
+
GR.setlinecolorind(1)
|
|
987
|
+
GR.polyline(kvs[:window][0..1], [0, 0])
|
|
988
|
+
|
|
989
|
+
when :bar
|
|
990
|
+
(0...x.length).step(2) do |i|
|
|
991
|
+
GR.setfillcolorind(989)
|
|
992
|
+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
|
993
|
+
GR.fillrect(x[i], x[i + 1], y[i], y[i + 1])
|
|
994
|
+
GR.setfillcolorind(1)
|
|
995
|
+
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
|
996
|
+
GR.fillrect(x[i], x[i + 1], y[i], y[i + 1])
|
|
727
997
|
end
|
|
728
|
-
GR.polymarker(x, y)
|
|
729
998
|
|
|
730
999
|
when :hist
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
GR.fillrect(xmin, x[i], y[i], y[i + 1])
|
|
740
|
-
end
|
|
741
|
-
else
|
|
742
|
-
ymin = kvs[:window][2]
|
|
743
|
-
y.length.times do |i|
|
|
744
|
-
GR.setfillcolorind(989)
|
|
745
|
-
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
|
746
|
-
GR.fillrect(x[i], x[i + 1], ymin, y[i])
|
|
747
|
-
GR.setfillcolorind(1)
|
|
748
|
-
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
|
749
|
-
GR.fillrect(x[i], x[i + 1], ymin, y[i])
|
|
750
|
-
end
|
|
1000
|
+
ymin = kvs[:window][2]
|
|
1001
|
+
y.length.times do |i|
|
|
1002
|
+
GR.setfillcolorind(989)
|
|
1003
|
+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
|
1004
|
+
GR.fillrect(x[i], x[i + 1], ymin, y[i])
|
|
1005
|
+
GR.setfillcolorind(1)
|
|
1006
|
+
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
|
1007
|
+
GR.fillrect(x[i], x[i + 1], ymin, y[i])
|
|
751
1008
|
end
|
|
752
1009
|
|
|
753
1010
|
when :polarhist
|
|
@@ -762,6 +1019,7 @@ module GR
|
|
|
762
1019
|
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
|
763
1020
|
GR.fillarc(-ρ[i], ρ[i], -ρ[i], ρ[i], θ[i - 1], θ[i])
|
|
764
1021
|
end
|
|
1022
|
+
draw_polar_axes(2)
|
|
765
1023
|
|
|
766
1024
|
when :polarheatmap, :nonuniformpolarheatmap
|
|
767
1025
|
w, h = z.shape
|
|
@@ -781,9 +1039,10 @@ module GR
|
|
|
781
1039
|
θ = x.map { |i| i * 180 / Math::PI }
|
|
782
1040
|
GR.nonuniformpolarcellarray(θ, ρ, w, h, colors)
|
|
783
1041
|
end
|
|
784
|
-
draw_polar_axes
|
|
1042
|
+
draw_polar_axes(1)
|
|
1043
|
+
draw_polar_axes(2)
|
|
785
1044
|
kvs[:zrange] = [cmin, cmax]
|
|
786
|
-
colorbar
|
|
1045
|
+
colorbar(0.025)
|
|
787
1046
|
|
|
788
1047
|
when :contour, :contourf
|
|
789
1048
|
zmin, zmax = kvs[:zrange]
|
|
@@ -816,7 +1075,12 @@ module GR
|
|
|
816
1075
|
when :contour
|
|
817
1076
|
GR._contour_(x, y, h, z, clabels ? 1 : 1000)
|
|
818
1077
|
when :contourf
|
|
819
|
-
|
|
1078
|
+
clines = kvs.has_key?(:clines) ? kvs[:clines] : true
|
|
1079
|
+
GR._contourf_(x, y, h, z, if clines
|
|
1080
|
+
clabels ? 1 : 0
|
|
1081
|
+
else
|
|
1082
|
+
-1
|
|
1083
|
+
end)
|
|
820
1084
|
end
|
|
821
1085
|
colorbar(0, h.length)
|
|
822
1086
|
|
|
@@ -831,12 +1095,11 @@ module GR
|
|
|
831
1095
|
when :heatmap, :nonuniformheatmap
|
|
832
1096
|
case z
|
|
833
1097
|
when Array
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
end
|
|
1098
|
+
raise unless z.all? { |zi| zi.size == z[0].size }
|
|
1099
|
+
|
|
1100
|
+
w = z.size
|
|
1101
|
+
h = z[0].size
|
|
1102
|
+
|
|
840
1103
|
when ->(obj) { narray?(obj) }
|
|
841
1104
|
w, h = z.shape
|
|
842
1105
|
else
|
|
@@ -846,11 +1109,11 @@ module GR
|
|
|
846
1109
|
cmin, cmax = kvs[:crange]
|
|
847
1110
|
levels = kvs[:levels] || 256
|
|
848
1111
|
data = z.flatten.to_a.map { |i| normalize_color(i, cmin, cmax) } # NArray -> Array
|
|
849
|
-
if kind == :heatmap
|
|
1112
|
+
if kind == :heatmap && !ENV['GR_SCALE_FACTOR']
|
|
850
1113
|
rgba = data.map { |v| to_rgba(v, cmap) }
|
|
851
1114
|
GR.drawimage(0.5, w + 0.5, h + 0.5, 0.5, w, h, rgba)
|
|
852
1115
|
else
|
|
853
|
-
colors = data.map { |i| (1000 + i * 255).round }
|
|
1116
|
+
colors = data.map { |i| (i.nan? ? 1256 : 1000 + i * 255).round }
|
|
854
1117
|
GR.nonuniformcellarray(x, y, w, h, colors)
|
|
855
1118
|
end
|
|
856
1119
|
colorbar(0, levels)
|
|
@@ -887,9 +1150,14 @@ module GR
|
|
|
887
1150
|
|
|
888
1151
|
when :volume
|
|
889
1152
|
algorithm = kvs[:algorithm] || 0
|
|
1153
|
+
w, h, ratio = GR.inqvpsize
|
|
1154
|
+
GR.setpicturesizeforvolume((w * ratio).round, (h * ratio).round)
|
|
890
1155
|
require 'gr3'
|
|
891
1156
|
GR3.clear
|
|
1157
|
+
ambient, diffuse, specular, specular_power = GR3.getlightparameters
|
|
1158
|
+
GR3.setlightparameters(0.8, 0.2, 0.1, 10.0)
|
|
892
1159
|
dmin, dmax = GR3.volume(z, algorithm)
|
|
1160
|
+
GR3.setlightparameters(ambient, diffuse, specular, specular_power)
|
|
893
1161
|
draw_axes(kind, 2)
|
|
894
1162
|
kvs[:zrange] = [dmin, dmax]
|
|
895
1163
|
colorbar(0.05)
|
|
@@ -924,6 +1192,7 @@ module GR
|
|
|
924
1192
|
when :polar
|
|
925
1193
|
GR.uselinespec(spec)
|
|
926
1194
|
plot_polar(x, y)
|
|
1195
|
+
draw_polar_axes(2)
|
|
927
1196
|
|
|
928
1197
|
when :trisurf
|
|
929
1198
|
GR.trisurface(x, y, z)
|
|
@@ -934,25 +1203,15 @@ module GR
|
|
|
934
1203
|
zmin, zmax = kvs[:zrange]
|
|
935
1204
|
levels = linspace(zmin, zmax, 20)
|
|
936
1205
|
GR.tricontour(x, y, z, levels)
|
|
1206
|
+
colorbar
|
|
937
1207
|
|
|
938
1208
|
when :shade
|
|
939
1209
|
xform = kvs[:xform] || 5
|
|
940
|
-
if x.
|
|
941
|
-
# How to check NArray?
|
|
1210
|
+
if (x.respond_to?(:isnan) && x.isnan.any?) || (x.is_a?(Array) && x.include?(Float::NAN))
|
|
942
1211
|
GR.shadelines(x, y, xform: xform)
|
|
943
1212
|
else
|
|
944
1213
|
GR.shadepoints(x, y, xform: xform)
|
|
945
1214
|
end
|
|
946
|
-
|
|
947
|
-
when :bar
|
|
948
|
-
0.step(x.length - 1, 2) do |i|
|
|
949
|
-
GR.setfillcolorind(989)
|
|
950
|
-
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
|
951
|
-
GR.fillrect(x[i], x[i + 1], y[i], y[i + 1])
|
|
952
|
-
GR.setfillcolorind(1)
|
|
953
|
-
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
|
954
|
-
GR.fillrect(x[i], x[i + 1], y[i], y[i + 1])
|
|
955
|
-
end
|
|
956
1215
|
end
|
|
957
1216
|
|
|
958
1217
|
GR.restorestate
|
|
@@ -960,13 +1219,13 @@ module GR
|
|
|
960
1219
|
|
|
961
1220
|
draw_legend if %i[line step scatter stem].include?(kind) && kvs.has_key?(:labels)
|
|
962
1221
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
end
|
|
1222
|
+
return unless kvs[:update]
|
|
1223
|
+
|
|
1224
|
+
GR.updatews
|
|
1225
|
+
# if GR.isinline()
|
|
1226
|
+
# restore_context()
|
|
1227
|
+
# return GR.show()
|
|
1228
|
+
# end
|
|
970
1229
|
|
|
971
1230
|
# flag && restore_context()
|
|
972
1231
|
end
|
|
@@ -1077,6 +1336,8 @@ module GR
|
|
|
1077
1336
|
|
|
1078
1337
|
# https://gist.github.com/rysk-t/8d1aef0fb67abde1d259#gistcomment-1925021
|
|
1079
1338
|
def linspace(low, high, num)
|
|
1339
|
+
return [low] if num == 1
|
|
1340
|
+
|
|
1080
1341
|
[*0..(num - 1)].collect { |i| low + i.to_f * (high - low) / (num - 1) }
|
|
1081
1342
|
end
|
|
1082
1343
|
|
|
@@ -1086,6 +1347,7 @@ module GR
|
|
|
1086
1347
|
i.is_a?(Array) && (i[0].is_a?(Array) || narray?(i[0]))
|
|
1087
1348
|
end
|
|
1088
1349
|
args.map do |xyzc|
|
|
1350
|
+
xyzc = xyzc.dup
|
|
1089
1351
|
spec = nil
|
|
1090
1352
|
case xyzc.last
|
|
1091
1353
|
when String
|
|
@@ -1094,20 +1356,28 @@ module GR
|
|
|
1094
1356
|
spec = xyzc.pop[:spec]
|
|
1095
1357
|
end
|
|
1096
1358
|
|
|
1097
|
-
x, y, z, c = xyzc.map
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
else # String
|
|
1104
|
-
i
|
|
1105
|
-
end
|
|
1359
|
+
x, y, z, c = xyzc.map { |i| plot_arg(i) }
|
|
1360
|
+
if xyzc.size == 1 && y.nil?
|
|
1361
|
+
y = x
|
|
1362
|
+
x = linspace(1, y.length, y.length)
|
|
1363
|
+
elsif y.respond_to?(:call)
|
|
1364
|
+
y = x.map { |i| y.call(i) }
|
|
1106
1365
|
end
|
|
1107
1366
|
[x, y, z, c, spec]
|
|
1108
1367
|
end
|
|
1109
1368
|
end
|
|
1110
1369
|
|
|
1370
|
+
def plot_arg(arg)
|
|
1371
|
+
if arg.is_a?(Array) || narray?(arg) || arg.nil? || arg.respond_to?(:call)
|
|
1372
|
+
arg
|
|
1373
|
+
elsif arg.respond_to?(:to_a)
|
|
1374
|
+
# Convert an Array-like class such as Daru::Vector to an Array
|
|
1375
|
+
arg.to_a
|
|
1376
|
+
else
|
|
1377
|
+
arg
|
|
1378
|
+
end
|
|
1379
|
+
end
|
|
1380
|
+
|
|
1111
1381
|
# Normalize a color c with the range [cmin, cmax]
|
|
1112
1382
|
# 0 <= normalize_color(c, cmin, cmax) <= 1
|
|
1113
1383
|
def normalize_color(c, cmin, cmax)
|
|
@@ -1148,6 +1418,18 @@ module GR
|
|
|
1148
1418
|
[a, b]
|
|
1149
1419
|
end
|
|
1150
1420
|
|
|
1421
|
+
def extrema(a)
|
|
1422
|
+
amin = Float::INFINITY
|
|
1423
|
+
amax = -Float::INFINITY
|
|
1424
|
+
a.each do |el|
|
|
1425
|
+
next if el.nil? || (el.is_a?(Float) && el.nan?)
|
|
1426
|
+
|
|
1427
|
+
amin = el if el < amin
|
|
1428
|
+
amax = el if el > amax
|
|
1429
|
+
end
|
|
1430
|
+
[amin, amax]
|
|
1431
|
+
end
|
|
1432
|
+
|
|
1151
1433
|
def minmax(kind)
|
|
1152
1434
|
xmin = ymin = zmin = cmin = Float::INFINITY
|
|
1153
1435
|
xmax = ymax = zmax = cmax = -Float::INFINITY
|
|
@@ -1158,10 +1440,10 @@ module GR
|
|
|
1158
1440
|
# duck typing for NArray
|
|
1159
1441
|
x = x.map { |v| v > 0 ? v : Float::NAN }
|
|
1160
1442
|
end
|
|
1161
|
-
x0, x1 = x
|
|
1443
|
+
x0, x1 = extrema(x)
|
|
1162
1444
|
xmin = [x0, xmin].min
|
|
1163
1445
|
xmax = [x1, xmax].max
|
|
1164
|
-
elsif kind
|
|
1446
|
+
elsif %i[volume isosurface].include?(kind)
|
|
1165
1447
|
xmin = -1
|
|
1166
1448
|
xmax = 1
|
|
1167
1449
|
else
|
|
@@ -1172,10 +1454,10 @@ module GR
|
|
|
1172
1454
|
if scale & GR::OPTION_Y_LOG != 0
|
|
1173
1455
|
y = y.map { |v| v > 0 ? v : Float::NAN }
|
|
1174
1456
|
end
|
|
1175
|
-
y0, y1 = y
|
|
1457
|
+
y0, y1 = extrema(y)
|
|
1176
1458
|
ymin = [y0, ymin].min
|
|
1177
1459
|
ymax = [y1, ymax].max
|
|
1178
|
-
elsif kind
|
|
1460
|
+
elsif %i[volume isosurface].include?(kind)
|
|
1179
1461
|
ymin = -1
|
|
1180
1462
|
ymax = 1
|
|
1181
1463
|
else
|
|
@@ -1186,18 +1468,24 @@ module GR
|
|
|
1186
1468
|
if scale & GR::OPTION_Z_LOG != 0
|
|
1187
1469
|
z = z.map { |v| v > 0 ? v : Float::NAN }
|
|
1188
1470
|
end
|
|
1189
|
-
z0, z1 = z
|
|
1471
|
+
z0, z1 = extrema(z)
|
|
1190
1472
|
zmin = [z0, zmin].min
|
|
1191
1473
|
zmax = [z1, zmax].max
|
|
1474
|
+
elsif %i[volume isosurface].include?(kind)
|
|
1475
|
+
zmin = -1
|
|
1476
|
+
zmax = 1
|
|
1477
|
+
else
|
|
1478
|
+
zmin = 0
|
|
1479
|
+
zmax = 1
|
|
1192
1480
|
end
|
|
1193
1481
|
if c
|
|
1194
|
-
c0, c1 = c
|
|
1482
|
+
c0, c1 = extrema(c)
|
|
1195
1483
|
cmin = [c0, cmin].min
|
|
1196
1484
|
cmax = [c1, cmax].max
|
|
1197
1485
|
elsif z
|
|
1198
|
-
|
|
1199
|
-
cmin = [
|
|
1200
|
-
cmax = [
|
|
1486
|
+
c0, c1 = extrema(z)
|
|
1487
|
+
cmin = [c0, cmin].min
|
|
1488
|
+
cmax = [c1, cmax].max
|
|
1201
1489
|
end
|
|
1202
1490
|
end
|
|
1203
1491
|
xmin, xmax = fix_minmax(xmin, xmax)
|
|
@@ -1205,9 +1493,9 @@ module GR
|
|
|
1205
1493
|
zmin, zmax = fix_minmax(zmin, zmax)
|
|
1206
1494
|
|
|
1207
1495
|
# kvs[:xlim], kvs[:ylim], kvs[:zlim] is supposed to be Array or Range
|
|
1208
|
-
kvs[:xrange] = [
|
|
1209
|
-
kvs[:yrange] = [
|
|
1210
|
-
kvs[:zrange] = [
|
|
1496
|
+
kvs[:xrange] = [kvs[:xlim]&.first || xmin, kvs[:xlim]&.last || xmax]
|
|
1497
|
+
kvs[:yrange] = [kvs[:ylim]&.first || ymin, kvs[:ylim]&.last || ymax]
|
|
1498
|
+
kvs[:zrange] = [kvs[:zlim]&.first || zmin, kvs[:zlim]&.last || zmax]
|
|
1211
1499
|
|
|
1212
1500
|
if kvs.has_key?(:clim)
|
|
1213
1501
|
c0, c1 = kvs[:clim]
|
|
@@ -1228,10 +1516,15 @@ module GR
|
|
|
1228
1516
|
def auto_tick(amin, amax)
|
|
1229
1517
|
scale = 10.0**Math.log10(amax - amin).truncate
|
|
1230
1518
|
tick_size = [5.0, 2.0, 1.0, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01]
|
|
1231
|
-
|
|
1232
|
-
|
|
1519
|
+
tick = 1.0
|
|
1520
|
+
tick_size.each_with_index do |tsize, i|
|
|
1521
|
+
n = ((amax - amin) / scale / tsize).truncate
|
|
1522
|
+
if n > 7
|
|
1523
|
+
tick = tick_size[i - 1]
|
|
1524
|
+
break
|
|
1525
|
+
end
|
|
1233
1526
|
end
|
|
1234
|
-
|
|
1527
|
+
tick * scale
|
|
1235
1528
|
end
|
|
1236
1529
|
|
|
1237
1530
|
def legend_size
|
|
@@ -1271,6 +1564,11 @@ module GR
|
|
|
1271
1564
|
create_plot(:step, *args)
|
|
1272
1565
|
end
|
|
1273
1566
|
|
|
1567
|
+
# (Plot) Draw one or more step or staircase plots.
|
|
1568
|
+
def stairs(*args)
|
|
1569
|
+
create_plot(:stairs, *args)
|
|
1570
|
+
end
|
|
1571
|
+
|
|
1274
1572
|
# (Plot) Draw one or more scatter plots.
|
|
1275
1573
|
def scatter(*args)
|
|
1276
1574
|
create_plot(:scatter, *args)
|
|
@@ -1291,46 +1589,88 @@ module GR
|
|
|
1291
1589
|
plt.plot_data
|
|
1292
1590
|
end
|
|
1293
1591
|
|
|
1592
|
+
# (Plot) Draw a heatmap.
|
|
1294
1593
|
# (Plot) Draw a heatmap.
|
|
1295
1594
|
def heatmap(*args)
|
|
1296
|
-
|
|
1297
|
-
args
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1595
|
+
kv = args.last.is_a?(Hash) ? args.pop : {}
|
|
1596
|
+
if args.length == 1
|
|
1597
|
+
z = args[0]
|
|
1598
|
+
z = Numo::DFloat.cast(z) if z.is_a?(Array)
|
|
1599
|
+
ysize, xsize = z.shape
|
|
1600
|
+
z = z.reshape(xsize, ysize)
|
|
1601
|
+
x = (1..xsize).to_a
|
|
1602
|
+
y = (1..ysize).to_a
|
|
1603
|
+
elsif args.length == 3
|
|
1604
|
+
x, y, z = args
|
|
1605
|
+
z = Numo::DFloat.cast(z) if z.is_a?(Array)
|
|
1606
|
+
else
|
|
1607
|
+
raise ArgumentError
|
|
1608
|
+
end
|
|
1301
1609
|
create_plot(:heatmap, kv) do |plt|
|
|
1302
|
-
plt.
|
|
1303
|
-
|
|
1304
|
-
|
|
1610
|
+
plt.args = [[x, y, z, nil, '']]
|
|
1611
|
+
end
|
|
1612
|
+
end
|
|
1613
|
+
|
|
1614
|
+
# (Plot) Draw a nonuniformheatmap.
|
|
1615
|
+
def nonuniformheatmap(*args)
|
|
1616
|
+
kv = args.last.is_a?(Hash) ? args.pop : {}
|
|
1617
|
+
if args.length == 1
|
|
1618
|
+
z = args[0]
|
|
1619
|
+
z = Numo::DFloat.cast(z) if z.is_a?(Array)
|
|
1620
|
+
ysize, xsize = z.shape
|
|
1621
|
+
z = z.reshape(xsize, ysize)
|
|
1622
|
+
x = (1..xsize).to_a
|
|
1623
|
+
y = (1..ysize).to_a
|
|
1624
|
+
elsif args.length == 3
|
|
1625
|
+
x, y, z = args
|
|
1626
|
+
z = Numo::DFloat.cast(z) if z.is_a?(Array)
|
|
1627
|
+
else
|
|
1628
|
+
raise ArgumentError
|
|
1629
|
+
end
|
|
1630
|
+
create_plot(:nonuniformheatmap, kv) do |plt|
|
|
1631
|
+
plt.args = [[x, y, z, nil, '']]
|
|
1305
1632
|
end
|
|
1306
1633
|
end
|
|
1307
1634
|
|
|
1308
1635
|
# (Plot) Draw a polarheatmap.
|
|
1309
1636
|
def polarheatmap(*args)
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1637
|
+
kv = args.last.is_a?(Hash) ? args.pop : {}
|
|
1638
|
+
if args.length == 1
|
|
1639
|
+
z = args[0]
|
|
1640
|
+
z = Numo::DFloat.cast(z) if z.is_a?(Array)
|
|
1641
|
+
ysize, xsize = z.shape
|
|
1642
|
+
z = z.reshape(xsize, ysize)
|
|
1643
|
+
x = (1..xsize).to_a
|
|
1644
|
+
y = (1..ysize).to_a
|
|
1645
|
+
elsif args.length == 3
|
|
1646
|
+
x, y, z = args
|
|
1647
|
+
z = Numo::DFloat.cast(z) if z.is_a?(Array)
|
|
1648
|
+
else
|
|
1649
|
+
raise ArgumentError
|
|
1650
|
+
end
|
|
1651
|
+
create_plot(:polarheatmap, kv) do |plt|
|
|
1652
|
+
plt.args = [[x, y, z, nil, '']]
|
|
1320
1653
|
end
|
|
1321
1654
|
end
|
|
1322
1655
|
|
|
1323
1656
|
# (Plot) Draw a nonuniformpolarheatmap.
|
|
1324
1657
|
def nonuniformpolarheatmap(*args)
|
|
1325
|
-
|
|
1326
|
-
args
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1658
|
+
kv = args.last.is_a?(Hash) ? args.pop : {}
|
|
1659
|
+
if args.length == 1
|
|
1660
|
+
z = args[0]
|
|
1661
|
+
z = Numo::DFloat.cast(z) if z.is_a?(Array)
|
|
1662
|
+
ysize, xsize = z.shape
|
|
1663
|
+
z = z.reshape(xsize, ysize)
|
|
1664
|
+
x = (1..xsize).to_a
|
|
1665
|
+
y = (1..ysize).to_a
|
|
1666
|
+
elsif args.length == 3
|
|
1667
|
+
x, y, z = args
|
|
1668
|
+
z = Numo::DFloat.cast(z) if z.is_a?(Array)
|
|
1669
|
+
else
|
|
1670
|
+
raise ArgumentError
|
|
1671
|
+
end
|
|
1330
1672
|
create_plot(:nonuniformpolarheatmap, kv) do |plt|
|
|
1331
|
-
plt.
|
|
1332
|
-
plt.kvs[:ylim] ||= [0.5, ysize + 0.5]
|
|
1333
|
-
plt.args = [[(1..xsize).to_a, (1..ysize).to_a, z, nil, '']]
|
|
1673
|
+
plt.args = [[x, y, z, nil, '']]
|
|
1334
1674
|
end
|
|
1335
1675
|
end
|
|
1336
1676
|
|
|
@@ -1402,18 +1742,29 @@ module GR
|
|
|
1402
1742
|
end
|
|
1403
1743
|
|
|
1404
1744
|
# (Plot) Draw a bar plot.
|
|
1405
|
-
def barplot(
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1745
|
+
def barplot(*args)
|
|
1746
|
+
kv = args.last.is_a?(Hash) ? args.pop : {}
|
|
1747
|
+
if args.length == 2
|
|
1748
|
+
labels, heights = args
|
|
1749
|
+
elsif args.length == 1
|
|
1750
|
+
heights = args[0]
|
|
1751
|
+
labels = (1..heights.length).map(&:to_s)
|
|
1752
|
+
else
|
|
1753
|
+
raise ArgumentError
|
|
1754
|
+
end
|
|
1755
|
+
|
|
1756
|
+
wc, hc = barcoordinates(heights, kv)
|
|
1757
|
+
horizontal = kv.delete(:horizontal)
|
|
1758
|
+
|
|
1759
|
+
create_plot(:bar, kv) do |plt|
|
|
1760
|
+
if horizontal
|
|
1410
1761
|
plt.args = [[hc, wc, nil, nil, '']]
|
|
1411
1762
|
plt.kvs[:yticks] = [1, 1]
|
|
1412
|
-
plt.kvs[:yticklabels] = labels
|
|
1763
|
+
plt.kvs[:yticklabels] = labels.map(&:to_s)
|
|
1413
1764
|
else
|
|
1414
1765
|
plt.args = [[wc, hc, nil, nil, '']]
|
|
1415
1766
|
plt.kvs[:xticks] = [1, 1]
|
|
1416
|
-
plt.kvs[:xticklabels] = labels
|
|
1767
|
+
plt.kvs[:xticklabels] = labels.map(&:to_s)
|
|
1417
1768
|
end
|
|
1418
1769
|
end
|
|
1419
1770
|
end
|
|
@@ -1423,17 +1774,13 @@ module GR
|
|
|
1423
1774
|
create_plot(:hist, series, kv) do |plt|
|
|
1424
1775
|
nbins = plt.kvs[:nbins] || 0
|
|
1425
1776
|
x, y = hist(series, nbins)
|
|
1426
|
-
plt.args =
|
|
1427
|
-
[[y, x, nil, nil, '']]
|
|
1428
|
-
else
|
|
1429
|
-
[[x, y, nil, nil, '']]
|
|
1430
|
-
end
|
|
1777
|
+
plt.args = [[x, y, nil, nil, '']]
|
|
1431
1778
|
end
|
|
1432
1779
|
end
|
|
1433
1780
|
|
|
1434
1781
|
# (Plot) Draw an image.
|
|
1435
1782
|
def imshow(img, kv = {})
|
|
1436
|
-
img = Numo::DFloat.cast(img)
|
|
1783
|
+
img = Numo::DFloat.cast(img) unless img.is_a?(String)
|
|
1437
1784
|
create_plot(:imshow, img, kv) do |plt|
|
|
1438
1785
|
plt.args = [[nil, nil, img, nil, '']]
|
|
1439
1786
|
end
|
|
@@ -1524,26 +1871,18 @@ module GR
|
|
|
1524
1871
|
end
|
|
1525
1872
|
|
|
1526
1873
|
def hist(x, nbins = 0)
|
|
1527
|
-
|
|
1528
|
-
begin
|
|
1529
|
-
require 'histogram/array'
|
|
1530
|
-
rescue LoadError => e
|
|
1531
|
-
e.message << " Please add gem 'histogram' to your project's Gemfile."
|
|
1532
|
-
raise e
|
|
1533
|
-
end
|
|
1534
|
-
x = x.to_a if narray?(x)
|
|
1535
|
-
x, y = x.histogram(nbins, bin_boundary: :min)
|
|
1536
|
-
x.push(x[-1] + x[1] - x[0])
|
|
1537
|
-
[x, y]
|
|
1874
|
+
GR::Plot::Histogram.hist(x, nbins)
|
|
1538
1875
|
end
|
|
1539
1876
|
|
|
1540
|
-
def barcoordinates(heights,
|
|
1877
|
+
def barcoordinates(heights, kv = {})
|
|
1878
|
+
barwidth = kv[:barwidth] || 0.8
|
|
1879
|
+
baseline = kv[:baseline] || 0.0
|
|
1541
1880
|
halfw = barwidth / 2.0
|
|
1542
1881
|
wc = []
|
|
1543
1882
|
hc = []
|
|
1544
1883
|
heights.each_with_index do |value, i|
|
|
1545
|
-
wc << i - halfw
|
|
1546
|
-
wc << i + halfw
|
|
1884
|
+
wc << (i + 1) - halfw
|
|
1885
|
+
wc << (i + 1) + halfw
|
|
1547
1886
|
hc << baseline
|
|
1548
1887
|
hc << value
|
|
1549
1888
|
end
|