ruby-gr 0.0.23 → 0.58.1.0

Sign up to get free protection for your applications and to get access to all the features.
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)