ruby-gr 0.0.23 → 0.58.1.0

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.
data/lib/gr/ffi.rb CHANGED
@@ -15,7 +15,7 @@ module GR
15
15
  raise LoadError, 'Could not find GR Framework'
16
16
  end
17
17
 
18
- extend GRCommons::Extern
18
+ extend GRCommons::TryExtern
19
19
 
20
20
  # https://github.com/sciapp/gr/blob/master/lib/gr/gr.h
21
21
  # keep same order
@@ -41,6 +41,8 @@ module GR
41
41
  'int, int, int, int, int, int, int *)'
42
42
  try_extern 'void gr_polarcellarray(double, double, double, double, double, double, ' \
43
43
  'int, int, int, int, int, int, int *)'
44
+ try_extern 'void gr_nonuniformpolarcellarray(double, double, double *, double *, ' \
45
+ 'int, int, int, int, int, int, int *);'
44
46
  try_extern 'void gr_gdp(int, double *, double *, int, int, int *)'
45
47
  try_extern 'void gr_spline(int, double *, double *, int, int)'
46
48
  try_extern 'void gr_gridit(int, double *, double *, double *, int, int, ' \
@@ -115,6 +117,7 @@ module GR
115
117
  try_extern 'void gr_setcolormap(int)'
116
118
  try_extern 'void gr_inqcolormap(int *)'
117
119
  try_extern 'void gr_setcolormapfromrgb(int n, double *r, double *g, double *b, double *x)'
120
+ try_extern 'void gr_inqcolormapinds(int *, int *)'
118
121
  try_extern 'void gr_colorbar(void)'
119
122
  try_extern 'void gr_inqcolor(int, int *)'
120
123
  try_extern 'int gr_inqcolorfromrgb(double, double, double)'
@@ -174,7 +177,7 @@ module GR
174
177
  try_extern 'void gr_shadepoints(int, double *, double *, int, int, int)'
175
178
  try_extern 'void gr_shadelines(int, double *, double *, int, int, int)'
176
179
  try_extern 'void gr_panzoom(double, double, double, double, double *, double *, double *, double *)'
177
- # try_extern 'int gr_findboundary(int, double *, double *, double, double (*)(double, double), int, int *)'
180
+ try_extern 'int gr_findboundary(int, double *, double *, double, double (*)(double, double), int, int *)'
178
181
  try_extern 'void gr_setresamplemethod(unsigned int flag)'
179
182
  try_extern 'void gr_inqresamplemethod(unsigned int *flag)'
180
183
  try_extern 'void gr_path(int, double *, double *, const char *)'
@@ -182,6 +185,8 @@ module GR
182
185
  try_extern 'void gr_inqborderwidth(double *)'
183
186
  try_extern 'void gr_setbordercolorind(int)'
184
187
  try_extern 'void gr_inqbordercolorind(int *)'
188
+ try_extern 'void gr_selectclipxform(int)'
189
+ try_extern 'void gr_inqclipxform(int *);'
185
190
  try_extern 'void gr_setprojectiontype(int)'
186
191
  try_extern 'void gr_inqprojectiontype(int *)'
187
192
  try_extern 'void gr_setperspectiveprojection(double, double, double)'
@@ -202,5 +207,7 @@ module GR
202
207
  try_extern 'void gr_inqtext3d(double, double, double, char *, int axis, double *, double *)'
203
208
  try_extern 'void gr_settextencoding(int)'
204
209
  try_extern 'void gr_inqtextencoding(int *)'
210
+ try_extern 'void gr_loadfont(char *, int *)'
211
+ # gr_setcallback(char *(*)(const char *));
205
212
  end
206
213
  end
data/lib/gr/plot.rb CHANGED
@@ -33,17 +33,53 @@ module GR
33
33
  # Plot kinds conform to GR.jl
34
34
  PLOT_KIND = %i[line step scatter stem hist contour contourf hexbin heatmap
35
35
  nonuniformheatmap wireframe surface plot3 scatter3 imshow
36
- isosurface polar polarhist polarheatmap trisurf tricont shade
37
- volume].freeze # the name might be changed in the future.
36
+ isosurface polar polarhist polarheatmap nonuniformpolarheatmap
37
+ trisurf tricont shade volume].freeze
38
38
 
39
39
  # Keyword options conform to GR.jl.
40
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
41
+ clabels clear clim color colormap crange figsize font grid
42
+ horizontal isovalue kind label labels levels linewidth location
43
+ nbins ratio rotation scale size spec subplot tilt title update
44
+ xaxis xflip xform xlabel xlim xlog xrange xticks yaxis yflip
45
+ ylabel ylim ylog zflip yrange yticks viewport vp where window
46
+ zaxis zlabel zlim zlog zrange zticks].freeze
47
+
48
+ FONTS = {
49
+ times_roman: 101,
50
+ times_italic: 102,
51
+ times_bold: 103,
52
+ times_bolditalic: 104,
53
+ helvetica_regular: 105,
54
+ helvetica_oblique: 106,
55
+ helvetica_bold: 107,
56
+ helvetica_boldoblique: 108,
57
+ courier_regular: 109,
58
+ courier_oblique: 110,
59
+ courier_bold: 111,
60
+ courier_boldoblique: 112,
61
+ symbol: 113,
62
+ bookman_light: 114,
63
+ bookman_lightitalic: 115,
64
+ bookman_demi: 116,
65
+ bookman_demiitalic: 117,
66
+ newcenturyschlbk_roman: 118,
67
+ newcenturyschlbk_italic: 119,
68
+ newcenturyschlbk_bold: 120,
69
+ newcenturyschlbk_bolditalic: 121,
70
+ avantgarde_book: 122,
71
+ avantgarde_bookoblique: 123,
72
+ avantgarde_demi: 124,
73
+ avantgarde_demioblique: 125,
74
+ palatino_roman: 126,
75
+ palatino_italic: 127,
76
+ palatino_bold: 128,
77
+ palatino_bolditalic: 129,
78
+ zapfchancery_mediumitalic: 130,
79
+ zapfdingbats: 131,
80
+ cmuserif_math: 232, # original: cmuserif-math
81
+ dejavusans: 233
82
+ }.freeze
47
83
 
48
84
  @last_plot = nil
49
85
  class << self
@@ -116,15 +152,20 @@ module GR
116
152
  vp1, vp2, vp3, vp4 = vp
117
153
  end
118
154
 
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
-
124
- if %i[contour contourf hexbin heatmap nonuniformheatmap polarheatmap
125
- surface trisurf volume].include?(kind)
126
- viewport[1] -= 0.1
127
- end
155
+ left_margin = kvs.has_key?(:ylabel) ? 0.05 : 0
156
+ right_margin = if %i[contour contourf hexbin heatmap nonuniformheatmap polarheatmap
157
+ nonuniformpolarheatmap surface trisurf volume].include?(kind)
158
+ (vp2 - vp1) * 0.1
159
+ else
160
+ 0
161
+ end
162
+ bottom_margin = kvs.has_key?(:xlabel) ? 0.05 : 0
163
+ top_margin = kvs.has_key?(:title) ? 0.075 : 0
164
+
165
+ viewport = [vp1 + (0.075 + left_margin) * (vp2 - vp1),
166
+ vp1 + (0.95 - right_margin) * (vp2 - vp1),
167
+ vp3 + (0.075 + bottom_margin) * (vp4 - vp3),
168
+ vp3 + (0.975 - top_margin) * (vp4 - vp3)]
128
169
 
129
170
  if %i[line step scatter stem].include?(kind) && kvs[:labels]
130
171
  location = kvs[:location] || 1
@@ -156,7 +197,7 @@ module GR
156
197
  GR.restorestate
157
198
  end
158
199
 
159
- if %i[polar polarhist polarheatmap].include? kind
200
+ if %i[polar polarhist polarheatmap nonuniformpolarheatmap].include? kind
160
201
  xmin, xmax, ymin, ymax = viewport
161
202
  xcenter = 0.5 * (xmin + xmax)
162
203
  ycenter = 0.5 * (ymin + ymax)
@@ -167,7 +208,7 @@ module GR
167
208
 
168
209
  def set_window(kind)
169
210
  scale = 0
170
- unless %i[polar polarhist polarheatmap].include?(kind)
211
+ unless %i[polar polarhist polarheatmap nonuniformpolarheatmap].include?(kind)
171
212
  scale |= GR::OPTION_X_LOG if kvs[:xlog]
172
213
  scale |= GR::OPTION_Y_LOG if kvs[:ylog]
173
214
  scale |= GR::OPTION_Z_LOG if kvs[:zlog]
@@ -182,11 +223,11 @@ module GR
182
223
  kvs[:xrange] = [xmin, xmax]
183
224
  kvs[:yrange] = [ymin, ymax]
184
225
  else
185
- minmax
226
+ minmax(kind)
186
227
  end
187
228
 
188
229
  major_count = if %i[wireframe surface plot3 scatter3 polar polarhist
189
- polarheatmap trisurf volume].include?(kind)
230
+ polarheatmap nonuniformpolarheatmap trisurf volume].include?(kind)
190
231
  2
191
232
  else
192
233
  5
@@ -202,15 +243,15 @@ module GR
202
243
  xmax += 0.5
203
244
  end
204
245
  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
246
+ if !%i[heatmap polarheatmap].include?(kind) &&
247
+ !kvs.has_key?(:xlim) &&
248
+ !kvs[:panzoom]
249
+ xmin, xmax = GR.adjustlimits(xmin, xmax)
209
250
  end
210
251
  if kvs.has_key?(:xticks)
211
252
  kvs[:xticks]
212
253
  else
213
- [GR.tick(xmin, xmax) / major_count, major_count]
254
+ [auto_tick(xmin, xmax) / major_count, major_count]
214
255
  end
215
256
  else
216
257
  [1, 1]
@@ -231,15 +272,15 @@ module GR
231
272
  end
232
273
  end
233
274
  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
275
+ if !%i[heatmap polarheatmap].include?(kind) &&
276
+ !kvs.has_key?(:ylim) &&
277
+ !kvs[:panzoom]
278
+ ymin, ymax = GR.adjustlimits(ymin, ymax)
238
279
  end
239
280
  if kvs.has_key?(:yticks)
240
281
  kvs[:yticks]
241
282
  else
242
- [GR.tick(ymin, ymax) / major_count, major_count]
283
+ [auto_tick(ymin, ymax) / major_count, major_count]
243
284
  end
244
285
  else
245
286
  [1, 1]
@@ -254,7 +295,7 @@ module GR
254
295
  if kvs.has_key?(:zticks)
255
296
  kvs[:zticks]
256
297
  else
257
- [GR.tick(zmin, zmax) / major_count, major_count]
298
+ [auto_tick(zmin, zmax) / major_count, major_count]
258
299
  end
259
300
  else
260
301
  [1, 1]
@@ -264,15 +305,16 @@ module GR
264
305
  end
265
306
 
266
307
  kvs[:window] = xmin, xmax, ymin, ymax
267
- if %i[polar polarhist polarheatmap].include?(kind)
308
+ if %i[polar polarhist polarheatmap nonuniformpolarheatmap trisurf].include?(kind)
268
309
  GR.setwindow(-1, 1, -1, 1)
269
310
  else
270
311
  GR.setwindow(xmin, xmax, ymin, ymax)
271
312
  end
272
313
  if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
273
314
  rotation = kvs[:rotation] || 40
274
- tilt = kvs[:tilt] || 70
275
- GR.setspace(zmin, zmax, rotation, tilt)
315
+ tilt = kvs[:tilt] || 60
316
+ GR.setwindow3d(xmin, xmax, ymin, ymax, zmin, zmax)
317
+ GR.setspace3d(-rotation, tilt, 30, 0)
276
318
  end
277
319
 
278
320
  kvs[:scale] = scale
@@ -291,10 +333,10 @@ module GR
291
333
  GR.setlinecolorind(1)
292
334
  diag = Math.sqrt((viewport[1] - viewport[0])**2 + (viewport[3] - viewport[2])**2)
293
335
  GR.setlinewidth(1)
294
- charheight = [0.018 * diag, 0.012].max
295
- GR.setcharheight(charheight)
296
336
  ticksize = 0.0075 * diag
297
337
  if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
338
+ charheight = [0.024 * diag, 0.012].max
339
+ GR.setcharheight(charheight)
298
340
  ztick, zorg, majorz = kvs[:zaxis]
299
341
  if pass == 1 && drawgrid
300
342
  GR.grid3d(xtick, 0, ztick, xorg[0], yorg[1], zorg[0], 2, 0, 2)
@@ -304,6 +346,8 @@ module GR
304
346
  GR.axes3d(0, ytick, 0, xorg[1], yorg[0], zorg[0], 0, majory, 0, ticksize)
305
347
  end
306
348
  else
349
+ charheight = [0.018 * diag, 0.012].max
350
+ GR.setcharheight(charheight)
307
351
  if %i[heatmap nonuniformheatmap shade].include?(kind)
308
352
  ticksize = -ticksize
309
353
  elsif drawgrid
@@ -345,29 +389,29 @@ module GR
345
389
  GR.axes(xtick, ytick, xorg[1], yorg[1], -majorx, -majory, -ticksize)
346
390
  end
347
391
 
348
- if kvs[:title]
392
+ if kvs.has_key?(:title)
349
393
  GR.savestate
350
394
  GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
351
- text(0.5 * (viewport[0] + viewport[1]), vp[3], kvs[:title])
395
+ text(0.5 * (viewport[0] + viewport[1]), vp[3], kvs[:title].to_s)
352
396
  GR.restorestate
353
397
  end
354
398
  if %i[wireframe surface plot3 scatter3 trisurf volume].include?(kind)
355
- xlabel = kvs[:xlabel] || ''
356
- ylabel = kvs[:ylabel] || ''
357
- zlabel = kvs[:zlabel] || ''
399
+ xlabel = (kvs[:xlabel] || '').to_s
400
+ ylabel = (kvs[:ylabel] || '').to_s
401
+ zlabel = (kvs[:zlabel] || '').to_s
358
402
  GR.titles3d(xlabel, ylabel, zlabel)
359
403
  else
360
404
  if kvs.has_key?(:xlabel)
361
405
  GR.savestate
362
406
  GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_BOTTOM)
363
- text(0.5 * (viewport[0] + viewport[1]), vp[2] + 0.5 * charheight, kvs[:xlabel])
407
+ text(0.5 * (viewport[0] + viewport[1]), vp[2] + 0.5 * charheight, kvs[:xlabel].to_s)
364
408
  GR.restorestate
365
409
  end
366
410
  if kvs.has_key?(:ylabel)
367
411
  GR.savestate
368
412
  GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
369
413
  GR.setcharup(-1, 0)
370
- text(vp[0] + 0.5 * charheight, 0.5 * (viewport[2] + viewport[3]), kvs[:ylabel])
414
+ text(vp[0] + 0.5 * charheight, 0.5 * (viewport[2] + viewport[3]), kvs[:ylabel].to_s)
371
415
  GR.restorestate
372
416
  end
373
417
  end
@@ -386,7 +430,7 @@ module GR
386
430
  GR.setcharheight(charheight)
387
431
  GR.setlinetype(GR::LINETYPE_SOLID)
388
432
 
389
- tick = 0.5 * GR.tick(rmin, rmax)
433
+ tick = auto_tick(rmin, rmax)
390
434
  n = ((rmax - rmin) / tick + 0.5).round
391
435
  (n + 1).times do |i|
392
436
  r = i.to_f / n
@@ -475,7 +519,7 @@ module GR
475
519
  if kvs.has_key?(:title)
476
520
  GR.savestate
477
521
  GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
478
- text(0.5 * (viewport[0] + viewport[1]), vp[3], kvs[:title])
522
+ text(0.5 * (viewport[0] + viewport[1]), vp[3], kvs[:title].to_s)
479
523
  GR.restorestate
480
524
  end
481
525
  GR.selntran(1)
@@ -548,7 +592,7 @@ module GR
548
592
  charheight = [0.016 * diag, 0.012].max
549
593
  GR.setcharheight(charheight)
550
594
  if kvs[:scale] & GR::OPTION_Z_LOG == 0
551
- ztick = 0.5 * GR.tick(zmin, zmax)
595
+ ztick = auto_tick(zmin, zmax)
552
596
  GR.axes(0, ztick, 1, zmin, 0, 1, 0.005)
553
597
  else
554
598
  GR.setscale(GR::OPTION_Y_LOG)
@@ -577,16 +621,34 @@ module GR
577
621
  # Not yet.
578
622
  end
579
623
 
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
624
+ if kvs.has_key?(:font)
625
+ name = kvs[:font]
626
+ # 'Cmuserif-Math' => :cmuserif_math
627
+ sym_name = name.to_s.gsub('-', '_').downcase.to_sym
628
+ if FONTS.include?(sym_name)
629
+ font = FONTS[sym_name]
630
+ GR.settextfontprec(font, font > 200 ? 3 : 0)
631
+ else
632
+ font = GR.loadfont(name)
633
+ if font >= 0
634
+ GR.settextfontprec(font, 3)
635
+ else
636
+ warn "Unknown font name: #{name}"
637
+ end
638
+ end
639
+ else
640
+ # The following fonts are the default in GR.jl
641
+ # Japanese, Chinese, Korean, etc. cannot be displayed.
642
+
643
+ # GR.settextfontprec(232, 3) # CM Serif Roman
644
+ end
583
645
 
584
646
  set_viewport(kind, kvs[:subplot])
585
647
  unless kvs[:ax]
586
648
  set_window(kind)
587
649
  if %i[polar polarhist].include?(kind)
588
650
  draw_polar_axes
589
- elsif !%i[imshow isosurface polarheatmap].include?(kind)
651
+ elsif !%i[imshow isosurface polarheatmap nonuniformpolarheatmap].include?(kind)
590
652
  draw_axes(kind)
591
653
  end
592
654
  end
@@ -607,8 +669,12 @@ module GR
607
669
 
608
670
  when :line
609
671
  mask = GR.uselinespec(spec)
610
- GR.polyline(x, y) if hasline(mask)
611
- GR.polymarker(x, y) if hasmarker(mask)
672
+ linewidth = kvs[:linewidth]
673
+ # Slightly different from Julia,
674
+ # Because the implementation of polyline and polymarker is different.
675
+ z ||= linewidth # FIXME
676
+ GR.polyline(x, y, z, c) if hasline(mask)
677
+ GR.polymarker(x, y, z, c) if hasmarker(mask)
612
678
 
613
679
  when :step
614
680
  mask = GR.uselinespec(spec)
@@ -644,20 +710,9 @@ module GR
644
710
 
645
711
  when :scatter
646
712
  GR.setmarkertype(GR::MARKERTYPE_SOLID_CIRCLE)
647
- if z || c
648
- if c
649
- cmin, cmax = kvs[:crange]
650
- c = c.map { |i| normalize_color(i, cmin, cmax) }
651
- cind = c.map { |i| (1000 + i * 255).round }
652
- end
653
- x.length.times do |i|
654
- GR.setmarkersize(z[i] / 100.0) if z
655
- GR.setmarkercolorind(cind[i]) if c
656
- GR.polymarker([x[i]], [y[i]])
657
- end
658
- else
659
- GR.polymarker(x, y)
660
- end
713
+ z = z&.map { |i| i * 0.01 }
714
+ c = c&.map { |i| normalize_color(i, *kvs[:crange]) }
715
+ GR.polymarker(x, y, z, c)
661
716
 
662
717
  when :stem
663
718
  GR.setlinecolorind(1)
@@ -707,7 +762,7 @@ module GR
707
762
  GR.fillarc(-ρ[i], ρ[i], -ρ[i], ρ[i], θ[i - 1], θ[i])
708
763
  end
709
764
 
710
- when :polarheatmap
765
+ when :polarheatmap, :nonuniformpolarheatmap
711
766
  w, h = z.shape
712
767
  cmap = colormap
713
768
  cmin, cmax = kvs[:zrange]
@@ -716,7 +771,15 @@ module GR
716
771
  data.reverse(axis: 1) if kvs[:yflip]
717
772
  colors = data * 255 + 1000
718
773
  colors = colors.transpose # Julia is column major
719
- GR.polarcellarray(0, 0, 0, 360, 0, 1, w, h, colors)
774
+ case kind
775
+ when :polarheatmap
776
+ GR.polarcellarray(0, 0, 0, 360, 0, 1, w, h, colors)
777
+ when :nonuniformpolarheatmap
778
+ ymax = y.max.to_f
779
+ ρ = y.map { |i| i / ymax }
780
+ θ = x.map { |i| i * 180 / Math::PI }
781
+ GR.nonuniformpolarcellarray(θ, ρ, w, h, colors)
782
+ end
720
783
  draw_polar_axes
721
784
  kvs[:zrange] = [cmin, cmax]
722
785
  colorbar
@@ -738,7 +801,7 @@ module GR
738
801
  zmin = kvs[:zlim].first if kvs[:zlim].first
739
802
  zmax = kvs[:zlim].last if kvs[:zlim].last
740
803
  end
741
-
804
+ GR.setprojectiontype(0)
742
805
  GR.setspace(zmin, zmax, 0, 90)
743
806
  levels = kvs[:levels] || 0
744
807
  clabels = kvs[:clabels] || false
@@ -748,9 +811,10 @@ module GR
748
811
  else
749
812
  h = levels
750
813
  end
751
- if kind == :contour
814
+ case kind
815
+ when :contour
752
816
  GR._contour_(x, y, h, z, clabels ? 1 : 1000)
753
- elsif kind == :contourf
817
+ when :contourf
754
818
  GR._contourf_(x, y, h, z, clabels ? 1 : 0)
755
819
  end
756
820
  colorbar(0, h.length)
@@ -972,7 +1036,7 @@ module GR
972
1036
 
973
1037
  def to_svg
974
1038
  ## Need IRuby improvemend.
975
- GR.show(false) if ENV['GKSwstype'] == 'svg'
1039
+ GR.show(false) if ENV['GKS_WSTYPE'] == 'svg'
976
1040
  end
977
1041
 
978
1042
  private
@@ -1045,8 +1109,8 @@ module GR
1045
1109
 
1046
1110
  # Normalize a color c with the range [cmin, cmax]
1047
1111
  # 0 <= normalize_color(c, cmin, cmax) <= 1
1048
- # Note: narray.map{|i| normalize_color(i)} There's room for speedup.
1049
1112
  def normalize_color(c, cmin, cmax)
1113
+ # NOTE: narray.map{|i| normalize_color(i)} There's room for speedup.
1050
1114
  c = c.to_f # if c is Integer
1051
1115
  c = c.clamp(cmin, cmax) - cmin
1052
1116
  c /= (cmax - cmin) if cmin != cmax
@@ -1054,6 +1118,7 @@ module GR
1054
1118
  end
1055
1119
 
1056
1120
  def inqtext(x, y, s)
1121
+ s = s.to_s
1057
1122
  if s.length >= 2 && s[0] == '$' && s[-1] == '$'
1058
1123
  GR.inqmathtex(x, y, s[1..-2])
1059
1124
  elsif s.include?('\\') || s.include?('_') || s.include?('^')
@@ -1064,6 +1129,7 @@ module GR
1064
1129
  end
1065
1130
 
1066
1131
  def text(x, y, s)
1132
+ s = s.to_s
1067
1133
  if s.length >= 2 && s[0] == '$' && s[-1] == '$'
1068
1134
  GR.mathtex(x, y, s[1..-2])
1069
1135
  elsif s.include?('\\') || s.include?('_') || s.include?('^')
@@ -1081,7 +1147,7 @@ module GR
1081
1147
  [a, b]
1082
1148
  end
1083
1149
 
1084
- def minmax
1150
+ def minmax(kind)
1085
1151
  xmin = ymin = zmin = cmin = Float::INFINITY
1086
1152
  xmax = ymax = zmax = cmax = -Float::INFINITY
1087
1153
  scale = kvs[:scale]
@@ -1094,6 +1160,8 @@ module GR
1094
1160
  x0, x1 = x.minmax
1095
1161
  xmin = [x0, xmin].min
1096
1162
  xmax = [x1, xmax].max
1163
+ elsif kind == :volume
1164
+ xmin, xmax = -1, 1
1097
1165
  else
1098
1166
  xmin = 0
1099
1167
  xmax = 1
@@ -1105,6 +1173,8 @@ module GR
1105
1173
  y0, y1 = y.minmax
1106
1174
  ymin = [y0, ymin].min
1107
1175
  ymax = [y1, ymax].max
1176
+ elsif kind == :volume
1177
+ ymin, ymax = -1, 1
1108
1178
  else
1109
1179
  ymin = 0
1110
1180
  ymax = 1
@@ -1146,6 +1216,21 @@ module GR
1146
1216
  end
1147
1217
  end
1148
1218
 
1219
+ def to_wc(wn)
1220
+ xmin, ymin = GR.ndctowc(wn[0], wn[2])
1221
+ xmax, ymax = GR.ndctowc(wn[1], wn[3])
1222
+ [xmin, xmax, ymin, ymax]
1223
+ end
1224
+
1225
+ def auto_tick(amin, amax)
1226
+ scale = 10.0**Math.log10(amax - amin).truncate
1227
+ tick_size = [5.0, 2.0, 1.0, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01]
1228
+ i = tick_size.find_index do |tsize|
1229
+ ((amax - amin) / scale / tsize) > 7 # maximum number of tick marks
1230
+ end
1231
+ tick = tick_size[i - 1] * scale
1232
+ end
1233
+
1149
1234
  def legend_size
1150
1235
  scale = GR.inqscale
1151
1236
  GR.selntran(0)
@@ -1163,20 +1248,12 @@ module GR
1163
1248
  [w, h]
1164
1249
  end
1165
1250
 
1166
- # NOTE: duplicated definition (GRCommonUtils)
1167
1251
  def equal_length(*args)
1168
- lengths = args.map(&:length)
1169
- unless lengths.all? { |l| l == lengths[0] }
1170
- raise ArgumentError,
1171
- 'Sequences must have same length.'
1172
- end
1173
-
1174
- lengths[0]
1252
+ GRCommons::GRCommonUtils.equal_length(*args)
1175
1253
  end
1176
1254
 
1177
- # NOTE: duplicated definition (GRCommonUtils)
1178
1255
  def narray?(data)
1179
- defined?(Numo::NArray) && data.is_a?(Numo::NArray)
1256
+ GRCommons::GRCommonUtils.narray?(data)
1180
1257
  end
1181
1258
  end
1182
1259
 
@@ -1240,6 +1317,20 @@ module GR
1240
1317
  end
1241
1318
  end
1242
1319
 
1320
+ # (Plot) Draw a nonuniformpolarheatmap.
1321
+ def nonuniformpolarheatmap(*args)
1322
+ # FIXME
1323
+ args, kv = format_xyzc(*args)
1324
+ _x, _y, z = args
1325
+ ysize, xsize = z.shape
1326
+ z = z.reshape(xsize, ysize)
1327
+ create_plot(:nonuniformpolarheatmap, kv) do |plt|
1328
+ plt.kvs[:xlim] ||= [0.5, xsize + 0.5]
1329
+ plt.kvs[:ylim] ||= [0.5, ysize + 0.5]
1330
+ plt.args = [[(1..xsize).to_a, (1..ysize).to_a, z, nil, '']]
1331
+ end
1332
+ end
1333
+
1243
1334
  alias _contour_ contour
1244
1335
  # (Plot) Draw a contour plot.
1245
1336
  def contour(*args)