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.
@@ -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 gr_transformationinterfaceforrepl(double, double, double, double)'
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
@@ -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 isovalue label labels
42
- levels location nbins rotation size tilt title where xflip
43
- xform xlabel xlim xlog yflip ylabel ylim ylog zflip zlabel zlim
44
- zlog clim subplot].freeze
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
- def initialize(*args)
52
- @kvs = if args[-1].is_a? Hash
53
- args.pop
54
- else
55
- {}
56
- end
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
- @kvs.each_key do |k|
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
- @kvs[:labels] = [@kvs[:label]] if @kvs[:label] && @kvs[:labels].nil?
64
-
65
- @args = plot_args(args) # method name is the same as Julia/Python
66
- @kvs[:size] ||= [600, 450]
67
- @kvs[:ax] = false if @kvs[:ax].nil?
68
- @kvs[:subplot] ||= [0, 1, 0, 1]
69
- @kvs[:clear] = true if @kvs[:clear].nil?
70
- @kvs[:update] = true if @kvs[:update].nil?
71
- @scheme = 0
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 = nil
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
- if kvs[:figsize]
81
- w = 0.0254 * width * kvs[:figsize][0] / mwidth
82
- h = 0.0254 * height * kvs[:figsize][1] / mheight
83
- else
84
- dpi = width / mwidth * 0.0254
85
- if dpi > 200
86
- w, h = kvs[:size].map { |x| x * dpi / 100 }
87
- else
88
- w, h = kvs[:size]
89
- end
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
- viewport[0] = vp1 + 0.125 * (vp2 - vp1)
118
- viewport[1] = vp1 + 0.925 * (vp2 - vp1)
119
- viewport[2] = vp3 + 0.125 * (vp4 - vp3)
120
- viewport[3] = vp3 + 0.925 * (vp4 - vp3)
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[0], viewport[1], viewport[2], viewport[3])
137
+ GR.setviewport(*viewport)
135
138
 
136
139
  kvs[:viewport] = viewport
137
- kvs[:vp] = vp
138
- kvs[:ratio] = 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 if kvs[:xlog]
169
- scale |= GR::OPTION_Y_LOG if kvs[:ylog]
170
- scale |= GR::OPTION_Z_LOG if kvs[:zlog]
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 (scale & GR::OPTION_X_LOG) == 0
193
- xmin, xmax = GR.adjustlimits(xmin, xmax) unless kvs.has_key?(:xlim) || kvs.has_key?(:panzoom)
194
- if kvs.has_key?(:xticks)
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
- xorg = if (scale & GR::OPTION_FLIP_X) == 0
204
- [xmin, xmax]
205
- else
206
- [xmax, xmin]
207
- end
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 == :hist && !kvs.has_key?(:ylim)
212
- ymin = (scale & GR::OPTION_Y_LOG) == 0 ? 0 : 1
222
+ if %i[heatmap polarheatmap].include?(kind) && kvs.has_key?(:ylim)
223
+ ymin -= 0.5
224
+ ymax += 0.5
213
225
  end
214
- if (scale & GR::OPTION_Y_LOG) == 0
215
- ymin, ymax = GR.adjustlimits(ymin, ymax) unless kvs.has_key?(:ylim) || kvs.has_key?(:panzoom)
216
- if kvs.has_key?(:yticks)
217
- ytick, majory = kvs[:yticks]
218
- else
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
- yorg = if (scale & GR::OPTION_FLIP_Y) == 0
226
- [ymin, ymax]
227
- else
228
- [ymax, ymin]
229
- end
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
- zmin, zmax = GR.adjustlimits(zmin, zmax) if kvs.has_key?(:zlim)
236
- if kvs.has_key?(:zticks)
237
- ztick, majorz = kvs[:zticks]
238
- else
239
- majorz = major_count
240
- ztick = GR.tick(zmin, zmax) / majorz
241
- end
242
- else
243
- ztick = majorz = 1
244
- end
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 = kvs[:tilt] || 70
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] || true
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
- else
297
- drawgrid && GR.grid(xtick, ytick, 0, 0, majorx, majory)
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.has_key?(:title)
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
- width, height = img.shape
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
- values = ((v - v.min) / (v.max - v.min) * (2 ^ 16 - 1)).round
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 ^ 16 - 1)).round)
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.settextfontprec(232, 3)
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.to_a if narray?(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
- ymin = kvs[:window][2]
660
- y.length.times do |i|
661
- GR.setfillcolorind(989)
662
- GR.setfillintstyle(GR::INTSTYLE_SOLID)
663
- GR.fillrect(x[i], x[i + 1], ymin, y[i])
664
- GR.setfillcolorind(1)
665
- GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
666
- GR.fillrect(x[i], x[i + 1], ymin, y[i])
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
- colors = data.map { |i| 1000 + i * 255 }
688
- # if kvs[:xflip]
689
- # if kvs[;yflip]
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 = kvs[:zlim] || z.minmax
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 = kvs[:zlim] || z.compact.minmax # compact : removed nil
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) } # NArray -> Array
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
- x.map! { |v| v > 0 ? v : Float::NAN }
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! { |v| v > 0 ? v : Float::NAN }
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! { |v| v > 0 ? v : Float::NAN }
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
- if kvs.has_key?(:xlim)
1095
- x0, x1 = kvs[:xlim]
1096
- x0 ||= xmin
1097
- x1 ||= xmax
1098
- kvs[:xrange] = [x0, x1]
1099
- else
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(x, kv = {})
1309
- create_plot(:hist, x, kv) do |plt|
1328
+ def histogram(series, kv = {})
1329
+ create_plot(:hist, series, kv) do |plt|
1310
1330
  nbins = plt.kvs[:nbins] || 0
1311
- x, y = hist(x, nbins)
1312
- plt.args = [[x, y, nil, nil, '']]
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.