ruby-gr 0.0.13 → 0.0.18
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/LICENSE.txt +24 -0
- data/README.md +58 -7
- data/lib/gr.rb +175 -57
- data/lib/gr/ffi.rb +14 -4
- data/lib/gr/grbase.rb +2 -3
- data/lib/gr/plot.rb +172 -136
- data/lib/gr3.rb +52 -41
- data/lib/gr3/ffi.rb +15 -5
- data/lib/gr3/gr3base.rb +2 -3
- data/lib/gr_commons/define_methods.rb +4 -4
- data/lib/gr_commons/extern.rb +2 -1
- data/lib/gr_commons/fiddley.rb +9 -10
- data/lib/gr_commons/gr_common_utils.rb +53 -27
- data/lib/gr_commons/gr_commons.rb +1 -1
- data/lib/gr_commons/version.rb +1 -1
- metadata +4 -3
data/lib/gr/ffi.rb
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
require 'fiddle/import'
|
4
4
|
|
5
5
|
module GR
|
6
|
-
# FFI Wrapper module for GR
|
6
|
+
# FFI Wrapper module for GR.
|
7
|
+
# The functions for GR are listed here.
|
8
|
+
# Add functions here when a new version of GR is released.
|
7
9
|
module FFI
|
8
10
|
extend Fiddle::Importer
|
9
11
|
|
@@ -16,8 +18,7 @@ module GR
|
|
16
18
|
extend GRCommons::Extern
|
17
19
|
|
18
20
|
# https://github.com/sciapp/gr/blob/master/lib/gr/gr.h
|
19
|
-
#
|
20
|
-
|
21
|
+
# keep same order
|
21
22
|
try_extern 'void gr_initgr(void)'
|
22
23
|
try_extern 'void gr_opengks(void)'
|
23
24
|
try_extern 'void gr_closegks(void)'
|
@@ -60,7 +61,9 @@ module GR
|
|
60
61
|
try_extern 'void gr_setcharexpan(double)'
|
61
62
|
try_extern 'void gr_setcharspace(double)'
|
62
63
|
try_extern 'void gr_settextcolorind(int)'
|
64
|
+
try_extern 'void gr_inqtextcolorind(int *)'
|
63
65
|
try_extern 'void gr_setcharheight(double)'
|
66
|
+
try_extern 'void gr_inqcharheight(double *)'
|
64
67
|
try_extern 'void gr_setcharup(double, double)'
|
65
68
|
try_extern 'void gr_settextpath(int)'
|
66
69
|
try_extern 'void gr_settextalign(int, int)'
|
@@ -159,7 +162,7 @@ module GR
|
|
159
162
|
try_extern 'void gr_selectcontext(int)'
|
160
163
|
try_extern 'void gr_destroycontext(int)'
|
161
164
|
try_extern 'int gr_uselinespec(char *)'
|
162
|
-
|
165
|
+
try_extern 'void gr_delaunay(int, const double *, const double *, int *, int **)'
|
163
166
|
try_extern 'void gr_reducepoints(int, const double *, const double *, int, double *, double *)'
|
164
167
|
try_extern 'void gr_trisurface(int, double *, double *, double *)'
|
165
168
|
try_extern 'void gr_gradient(int, int, double *, double *, double *, double *, double *)'
|
@@ -192,5 +195,12 @@ module GR
|
|
192
195
|
try_extern 'void gr_camerainteraction(double, double, double, double)'
|
193
196
|
try_extern 'void gr_setwindow3d(double, double, double, double, double, double)'
|
194
197
|
try_extern 'void gr_inqwindow3d(double *, double *, double *, double *, double *, double *)'
|
198
|
+
try_extern 'void gr_setscalefactors3d(double, double, double)'
|
199
|
+
try_extern 'void gr_inqscalefactors3d(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 *)'
|
195
205
|
end
|
196
206
|
end
|
data/lib/gr/grbase.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module GR
|
4
|
-
# This module automatically converts Ruby arrays and Numo::Narray into
|
4
|
+
# This module automatically converts Ruby arrays and Numo::Narray into
|
5
|
+
# Fiddley::MemoryPointer.
|
5
6
|
module GRBase
|
6
7
|
extend GRCommons::DefineMethods
|
7
8
|
define_ffi_methods(FFI,
|
@@ -9,6 +10,4 @@ module GR
|
|
9
10
|
default_type: :double)
|
10
11
|
end
|
11
12
|
private_constant :GRBase
|
12
|
-
|
13
|
-
extend GRCommons::GRCommonUtils
|
14
13
|
end
|
data/lib/gr/plot.rb
CHANGED
@@ -8,7 +8,9 @@ autoload :GR3, 'gr3'
|
|
8
8
|
require 'numo/narray'
|
9
9
|
|
10
10
|
module GR
|
11
|
-
class
|
11
|
+
# This class offers a simple, matlab-style API built on top of the GR package.
|
12
|
+
# The class name Plot may be changed in the future.
|
13
|
+
class Plot
|
12
14
|
# Why is the Plot class NOT object-oriented?
|
13
15
|
#
|
14
16
|
# Because the code here is mainly ported from GR.jl.
|
@@ -36,14 +38,14 @@ module GR
|
|
36
38
|
|
37
39
|
# Keyword options conform to GR.jl.
|
38
40
|
KW_ARGS = %i[accelerate algorithm alpha backgroundcolor barwidth baseline
|
39
|
-
clabels color colormap figsize isovalue label labels
|
40
|
-
location nbins rotation size tilt title where xflip
|
41
|
-
xlim xlog yflip ylabel ylim ylog zflip zlabel zlim
|
42
|
-
subplot].freeze
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
45
|
+
|
46
|
+
@last_plot = nil
|
47
|
+
class << self
|
48
|
+
attr_accessor :last_plot
|
47
49
|
end
|
48
50
|
|
49
51
|
def initialize(*args)
|
@@ -62,14 +64,14 @@ module GR
|
|
62
64
|
|
63
65
|
@args = plot_args(args) # method name is the same as Julia/Python
|
64
66
|
@kvs[:size] ||= [600, 450]
|
65
|
-
@kvs[:ax]
|
67
|
+
@kvs[:ax] = false if @kvs[:ax].nil?
|
66
68
|
@kvs[:subplot] ||= [0, 1, 0, 1]
|
67
|
-
@kvs[:clear]
|
68
|
-
@kvs[:update]
|
69
|
+
@kvs[:clear] = true if @kvs[:clear].nil?
|
70
|
+
@kvs[:update] = true if @kvs[:update].nil?
|
69
71
|
@scheme = 0
|
70
72
|
@background = 0xffffff
|
71
73
|
@handle = nil
|
72
|
-
|
74
|
+
self.class.last_plot = self
|
73
75
|
end
|
74
76
|
attr_accessor :args, :kvs, :scheme
|
75
77
|
|
@@ -170,6 +172,7 @@ module GR
|
|
170
172
|
scale |= GR::OPTION_FLIP_Y if kvs[:yflip]
|
171
173
|
scale |= GR::OPTION_FLIP_Z if kvs[:zflip]
|
172
174
|
end
|
175
|
+
kvs[:scale] = scale
|
173
176
|
if kvs.has_key?(:panzoom)
|
174
177
|
xmin, xmax, ymin, ymax = GR.panzoom(*kvs[:panzoom])
|
175
178
|
kvs[:xrange] = [xmin, xmax]
|
@@ -329,7 +332,7 @@ module GR
|
|
329
332
|
GR.axes(xtick, ytick, xorg[1], yorg[1], -majorx, -majory, -ticksize)
|
330
333
|
end
|
331
334
|
|
332
|
-
if kvs
|
335
|
+
if kvs[:title]
|
333
336
|
GR.savestate
|
334
337
|
GR.settextalign(GR::TEXT_HALIGN_CENTER, GR::TEXT_VALIGN_TOP)
|
335
338
|
text(0.5 * (viewport[0] + viewport[1]), vp[3], kvs[:title])
|
@@ -397,11 +400,9 @@ module GR
|
|
397
400
|
end
|
398
401
|
|
399
402
|
def plot_polar(θ, ρ)
|
400
|
-
ρ = Numo::DFloat.cast(ρ) if ρ.is_a? Array
|
401
403
|
window = kvs[:window]
|
402
|
-
|
403
|
-
|
404
|
-
ρ = (ρ - rmin) / (rmax - rmin)
|
404
|
+
rmax = window[3].to_f
|
405
|
+
ρ = ρ.map { |i| i / rmax }
|
405
406
|
n = ρ.length
|
406
407
|
x = []
|
407
408
|
y = []
|
@@ -420,7 +421,7 @@ module GR
|
|
420
421
|
if img.is_a? String
|
421
422
|
width, height, data = GR.readimage(img)
|
422
423
|
else
|
423
|
-
|
424
|
+
height, width = img.shape
|
424
425
|
cmin, cmax = kvs[:crange]
|
425
426
|
data = img.map { |i| normalize_color(i, cmin, cmax) }
|
426
427
|
data = data.map { |i| (1000 + i * 255).round }
|
@@ -487,7 +488,9 @@ module GR
|
|
487
488
|
end
|
488
489
|
|
489
490
|
GR.selntran(0)
|
490
|
-
|
491
|
+
v = Numo::DFloat.cast(v) if v.is_a? Array
|
492
|
+
values = ((v - v.min) / (v.max - v.min) * (2**16 - 1)).round
|
493
|
+
values = Numo::UInt16.cast(values)
|
491
494
|
nx, ny, nz = v.shape
|
492
495
|
isovalue = ((kvs[:isovalue] || 0.5) - v.min) / (v.max - v.min)
|
493
496
|
rotation = ((kvs[:rotation] || 40) * Math::PI / 180.0)
|
@@ -496,7 +499,7 @@ module GR
|
|
496
499
|
GR3.clear
|
497
500
|
mesh = GR3.createisosurfacemesh(values, [2.0 / (nx - 1), 2.0 / (ny - 1), 2.0 / (nz - 1)],
|
498
501
|
[-1, -1, -1],
|
499
|
-
(isovalue * (2
|
502
|
+
(isovalue * (2**16 - 1)).round)
|
500
503
|
color = kvs[:color] || [0.0, 0.5, 0.8]
|
501
504
|
GR3.setbackgroundcolor(1, 1, 1, 0)
|
502
505
|
GR3.drawmesh(mesh, 1, [0, 0, 0], [0, 0, 1], [0, 1, 0], color, [1, 1, 1])
|
@@ -561,6 +564,8 @@ module GR
|
|
561
564
|
# Not yet.
|
562
565
|
end
|
563
566
|
|
567
|
+
GR.settextfontprec(232, 3)
|
568
|
+
|
564
569
|
set_viewport(kind, kvs[:subplot])
|
565
570
|
unless kvs[:ax]
|
566
571
|
set_window(kind)
|
@@ -579,8 +584,7 @@ module GR
|
|
579
584
|
|
580
585
|
GR.uselinespec(' ')
|
581
586
|
args.each do |x, y, z, c, spec|
|
582
|
-
|
583
|
-
spec ||= ''
|
587
|
+
spec ||= kvs[:spec] ||= ''
|
584
588
|
GR.savestate
|
585
589
|
GR.settransparency(kvs[:alpha]) if kvs.has_key?(:alpha)
|
586
590
|
|
@@ -664,21 +668,18 @@ module GR
|
|
664
668
|
GR.fillrect(x[i], x[i + 1], ymin, y[i])
|
665
669
|
end
|
666
670
|
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
# GR.fillarea([0, ρ[i] * Math.cos(θ[i]), ρ[i] * Math.cos(θ[i + 1])],
|
680
|
-
# [0, ρ[i] * Math.sin(θ[i]), ρ[i] * Math.sin(θ[i + 1])])
|
681
|
-
# end
|
671
|
+
when :polarhist
|
672
|
+
ymax = kvs[:window][3].to_f
|
673
|
+
ρ = y.map { |i| i / ymax }
|
674
|
+
θ = x.map { |i| i * 180 / Math::PI }
|
675
|
+
(1...ρ.length).each do |i|
|
676
|
+
GR.setfillcolorind(989)
|
677
|
+
GR.setfillintstyle(GR::INTSTYLE_SOLID)
|
678
|
+
GR.fillarc(-ρ[i], ρ[i], -ρ[i], ρ[i], θ[i - 1], θ[i])
|
679
|
+
GR.setfillcolorind(1)
|
680
|
+
GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
|
681
|
+
GR.fillarc(-ρ[i], ρ[i], -ρ[i], ρ[i], θ[i - 1], θ[i])
|
682
|
+
end
|
682
683
|
|
683
684
|
when :polarheatmap
|
684
685
|
w, h = z.shape
|
@@ -699,11 +700,18 @@ module GR
|
|
699
700
|
a, b = z.shape
|
700
701
|
x = (1..b).to_a
|
701
702
|
y = (1..a).to_a
|
702
|
-
zmin, zmax =
|
703
|
+
zmin, zmax = z.minmax
|
703
704
|
elsif equal_length(x, y, z)
|
704
705
|
x, y, z = GR.gridit(x, y, z, 200, 200)
|
705
|
-
zmin, zmax =
|
706
|
+
zmin, zmax = z.compact.minmax # compact : removed nil
|
707
|
+
end
|
708
|
+
|
709
|
+
# kvs[:zlim] is supposed to be Array or Range
|
710
|
+
if kvs.has_key?(:zlim)
|
711
|
+
zmin = kvs[:zlim].first if kvs[:zlim].first
|
712
|
+
zmax = kvs[:zlim].last if kvs[:zlim].last
|
706
713
|
end
|
714
|
+
|
707
715
|
GR.setspace(zmin, zmax, 0, 90)
|
708
716
|
levels = kvs[:levels] || 0
|
709
717
|
clabels = kvs[:clabels] || false
|
@@ -795,7 +803,9 @@ module GR
|
|
795
803
|
colorbar(0.05)
|
796
804
|
|
797
805
|
when :plot3
|
798
|
-
GR.
|
806
|
+
mask = GR.uselinespec(spec)
|
807
|
+
GR.polyline3d(x, y, z) if hasline(mask)
|
808
|
+
GR.polymarker3d(x, y, z) if hasmarker(mask)
|
799
809
|
draw_axes(kind, 2)
|
800
810
|
|
801
811
|
when :scatter3
|
@@ -824,7 +834,7 @@ module GR
|
|
824
834
|
plot_polar(x, y)
|
825
835
|
|
826
836
|
when :trisurf
|
827
|
-
GR.
|
837
|
+
GR.trisurface(x, y, z)
|
828
838
|
draw_axes(kind, 2)
|
829
839
|
colorbar(0.05)
|
830
840
|
|
@@ -858,7 +868,7 @@ module GR
|
|
858
868
|
|
859
869
|
draw_legend if %i[line step scatter stem].include?(kind) && kvs.has_key?(:labels)
|
860
870
|
|
861
|
-
if kvs
|
871
|
+
if kvs[:update]
|
862
872
|
GR.updatews
|
863
873
|
# if GR.isinline()
|
864
874
|
# restore_context()
|
@@ -978,24 +988,31 @@ module GR
|
|
978
988
|
[*0..(num - 1)].collect { |i| low + i.to_f * (high - low) / (num - 1) }
|
979
989
|
end
|
980
990
|
|
981
|
-
def plot_args(args
|
991
|
+
def plot_args(args)
|
982
992
|
# FIXME
|
983
993
|
args = [args] unless args.all? do |i|
|
984
994
|
i.is_a?(Array) && (i[0].is_a?(Array) || narray?(i[0]))
|
985
995
|
end
|
986
996
|
args.map do |xyzc|
|
997
|
+
spec = nil
|
998
|
+
case xyzc.last
|
999
|
+
when String
|
1000
|
+
spec = xyzc.pop
|
1001
|
+
when Hash
|
1002
|
+
spec = xyzc.pop[:spec]
|
1003
|
+
end
|
1004
|
+
|
987
1005
|
x, y, z, c = xyzc.map do |i|
|
988
|
-
if i.is_a?(Array) || narray?(i)
|
1006
|
+
if i.is_a?(Array) || narray?(i) || i.nil?
|
989
1007
|
i
|
990
1008
|
elsif i.respond_to?(:to_a)
|
991
1009
|
# Convert an Array-like class such as Daru::Vector to an Array
|
992
1010
|
i.to_a
|
993
|
-
else
|
994
|
-
# String
|
1011
|
+
else # String
|
995
1012
|
i
|
996
1013
|
end
|
997
1014
|
end
|
998
|
-
[x, y, z, c]
|
1015
|
+
[x, y, z, c, spec]
|
999
1016
|
end
|
1000
1017
|
end
|
1001
1018
|
|
@@ -1038,9 +1055,12 @@ module GR
|
|
1038
1055
|
def minmax
|
1039
1056
|
xmin = ymin = zmin = cmin = Float::INFINITY
|
1040
1057
|
xmax = ymax = zmax = cmax = -Float::INFINITY
|
1041
|
-
|
1058
|
+
scale = kvs[:scale]
|
1042
1059
|
args.each do |x, y, z, c|
|
1043
1060
|
if x
|
1061
|
+
if scale & GR::OPTION_X_LOG != 0
|
1062
|
+
x.map! { |v| v > 0 ? v : Float::NAN }
|
1063
|
+
end
|
1044
1064
|
x0, x1 = x.minmax
|
1045
1065
|
xmin = [x0, xmin].min
|
1046
1066
|
xmax = [x1, xmax].max
|
@@ -1049,6 +1069,9 @@ module GR
|
|
1049
1069
|
xmax = 1
|
1050
1070
|
end
|
1051
1071
|
if y
|
1072
|
+
if scale & GR::OPTION_Y_LOG != 0
|
1073
|
+
y.map! { |v| v > 0 ? v : Float::NAN }
|
1074
|
+
end
|
1052
1075
|
y0, y1 = y.minmax
|
1053
1076
|
ymin = [y0, ymin].min
|
1054
1077
|
ymax = [y1, ymax].max
|
@@ -1057,6 +1080,9 @@ module GR
|
|
1057
1080
|
ymax = 1
|
1058
1081
|
end
|
1059
1082
|
if z
|
1083
|
+
if scale & GR::OPTION_Z_LOG != 0
|
1084
|
+
z.map! { |v| v > 0 ? v : Float::NAN }
|
1085
|
+
end
|
1060
1086
|
z0, z1 = z.minmax
|
1061
1087
|
zmin = [z0, zmin].min
|
1062
1088
|
zmax = [z1, zmax].max
|
@@ -1074,30 +1100,12 @@ module GR
|
|
1074
1100
|
xmin, xmax = fix_minmax(xmin, xmax)
|
1075
1101
|
ymin, ymax = fix_minmax(ymin, ymax)
|
1076
1102
|
zmin, zmax = fix_minmax(zmin, zmax)
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
kvs[:xrange] = [xmin, xmax]
|
1084
|
-
end
|
1085
|
-
if kvs.has_key?(:ylim)
|
1086
|
-
y0, y1 = kvs[:ylim]
|
1087
|
-
y0 ||= ymin
|
1088
|
-
y1 ||= ymax
|
1089
|
-
kvs[:yrange] = [y0, y1]
|
1090
|
-
else
|
1091
|
-
kvs[:yrange] = [ymin, ymax]
|
1092
|
-
end
|
1093
|
-
if kvs.has_key?(:zlim)
|
1094
|
-
z0, z1 = kvs[:zlim]
|
1095
|
-
z0 ||= zmin
|
1096
|
-
z1 ||= zmax
|
1097
|
-
kvs[:zrange] = [z0, z1]
|
1098
|
-
else
|
1099
|
-
kvs[:zrange] = [zmin, zmax]
|
1100
|
-
end
|
1103
|
+
|
1104
|
+
# kvs[:xlim], kvs[:ylim], kvs[:zlim] is supposed to be Array or Range
|
1105
|
+
kvs[:xrange] = [(kvs[:xlim]&.first || xmin), (kvs[:xlim]&.last || xmax)]
|
1106
|
+
kvs[:yrange] = [(kvs[:ylim]&.first || ymin), (kvs[:ylim]&.last || ymax)]
|
1107
|
+
kvs[:zrange] = [(kvs[:zlim]&.first || zmin), (kvs[:zlim]&.last || zmax)]
|
1108
|
+
|
1101
1109
|
if kvs.has_key?(:clim)
|
1102
1110
|
c0, c1 = kvs[:clim]
|
1103
1111
|
c0 ||= cmin
|
@@ -1117,7 +1125,7 @@ module GR
|
|
1117
1125
|
kvs[:labels].each do |label|
|
1118
1126
|
label = label.to_s
|
1119
1127
|
tbx, tby = inqtext(0, 0, label)
|
1120
|
-
w = [w, tbx[2]].max
|
1128
|
+
w = [w, tbx[2] - tbx[0]].max
|
1121
1129
|
h += [tby[2] - tby[0], 0.03].max
|
1122
1130
|
end
|
1123
1131
|
GR.setscale(scale)
|
@@ -1143,39 +1151,41 @@ module GR
|
|
1143
1151
|
end
|
1144
1152
|
|
1145
1153
|
class << self
|
1146
|
-
# Draw one or more line plots.
|
1154
|
+
# (Plot) Draw one or more line plots.
|
1147
1155
|
def plot(*args)
|
1148
1156
|
create_plot(:line, *args)
|
1149
1157
|
end
|
1150
1158
|
|
1151
|
-
# Draw one or more step or staircase plots.
|
1159
|
+
# (Plot) Draw one or more step or staircase plots.
|
1152
1160
|
def step(*args)
|
1153
1161
|
create_plot(:step, *args)
|
1154
1162
|
end
|
1155
1163
|
|
1156
|
-
# Draw one or more scatter plots.
|
1164
|
+
# (Plot) Draw one or more scatter plots.
|
1157
1165
|
def scatter(*args)
|
1158
1166
|
create_plot(:scatter, *args)
|
1159
1167
|
end
|
1160
1168
|
|
1161
|
-
# Draw a stem plot.
|
1169
|
+
# (Plot) Draw a stem plot.
|
1162
1170
|
def stem(*args)
|
1163
1171
|
create_plot(:stem, *args)
|
1164
1172
|
end
|
1165
1173
|
|
1166
|
-
#
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
+
# (Plot)
|
1175
|
+
def polarhistogram(x, kv = {})
|
1176
|
+
plt = GR::Plot.new(x, kv)
|
1177
|
+
plt.kvs[:kind] = :polarhist
|
1178
|
+
nbins = plt.kvs[:nbins] || 0
|
1179
|
+
x, y = hist(x, nbins)
|
1180
|
+
plt.args = [[x, y, nil, nil, '']]
|
1181
|
+
plt.plot_data
|
1182
|
+
end
|
1174
1183
|
|
1175
|
-
# Draw a heatmap.
|
1184
|
+
# (Plot) Draw a heatmap.
|
1176
1185
|
def heatmap(*args)
|
1177
1186
|
# FIXME
|
1178
|
-
|
1187
|
+
args, kv = format_xyzc(*args)
|
1188
|
+
_x, _y, z = args
|
1179
1189
|
ysize, xsize = z.shape
|
1180
1190
|
z = z.reshape(xsize, ysize)
|
1181
1191
|
create_plot(:heatmap, kv) do |plt|
|
@@ -1185,6 +1195,7 @@ module GR
|
|
1185
1195
|
end
|
1186
1196
|
end
|
1187
1197
|
|
1198
|
+
# (Plot) Draw a polarheatmap.
|
1188
1199
|
def polarheatmap(*args)
|
1189
1200
|
d = args.shift
|
1190
1201
|
# FIXME
|
@@ -1200,77 +1211,73 @@ module GR
|
|
1200
1211
|
end
|
1201
1212
|
|
1202
1213
|
alias _contour_ contour
|
1203
|
-
# Draw a contour plot.
|
1214
|
+
# (Plot) Draw a contour plot.
|
1204
1215
|
def contour(*args)
|
1205
|
-
|
1206
|
-
create_plot(:contour, x, y, z, kv)
|
1216
|
+
create_plot(:contour, *format_xyzc(*args))
|
1207
1217
|
end
|
1208
1218
|
|
1209
1219
|
alias _contourf_ contourf
|
1210
|
-
# Draw a filled contour plot.
|
1220
|
+
# (Plot) Draw a filled contour plot.
|
1211
1221
|
def contourf(*args)
|
1212
|
-
|
1213
|
-
create_plot(:contourf, x, y, z, kv)
|
1222
|
+
create_plot(:contourf, *format_xyzc(*args))
|
1214
1223
|
end
|
1215
1224
|
|
1216
1225
|
alias _hexbin_ hexbin
|
1217
|
-
# Draw a hexagon binning plot.
|
1226
|
+
# (Plot) Draw a hexagon binning plot.
|
1218
1227
|
def hexbin(*args)
|
1219
1228
|
create_plot(:hexbin, *args)
|
1220
1229
|
end
|
1221
1230
|
|
1222
|
-
# Draw a triangular contour plot.
|
1231
|
+
# (Plot) Draw a triangular contour plot.
|
1223
1232
|
def tricont(*args)
|
1224
|
-
|
1225
|
-
create_plot(:tricont, x, y, z, kv)
|
1233
|
+
create_plot(:tricont, *format_xyzc(*args))
|
1226
1234
|
end
|
1227
1235
|
|
1228
|
-
# Draw a three-dimensional wireframe plot.
|
1236
|
+
# (Plot) Draw a three-dimensional wireframe plot.
|
1229
1237
|
def wireframe(*args)
|
1230
|
-
|
1231
|
-
create_plot(:wireframe, x, y, z, kv)
|
1238
|
+
create_plot(:wireframe, *format_xyzc(*args))
|
1232
1239
|
end
|
1233
1240
|
|
1234
|
-
# Draw a three-dimensional surface plot.
|
1241
|
+
# (Plot) Draw a three-dimensional surface plot.
|
1235
1242
|
alias _surface_ surface
|
1236
1243
|
def surface(*args)
|
1237
|
-
|
1238
|
-
create_plot(:surface, x, y, z, kv)
|
1244
|
+
create_plot(:surface, *format_xyzc(*args))
|
1239
1245
|
end
|
1240
1246
|
|
1247
|
+
# (Plot)
|
1241
1248
|
def polar(*args)
|
1242
1249
|
create_plot(:polar, *args)
|
1243
1250
|
end
|
1244
1251
|
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
x, y, z, kv = parse_args(*args)
|
1249
|
-
create_plot(:trisurf, x, y, z, kv)
|
1252
|
+
# (Plot) Draw a triangular surface plot.
|
1253
|
+
def trisurf(*args)
|
1254
|
+
create_plot(:trisurf, *format_xyzc(*args))
|
1250
1255
|
end
|
1251
1256
|
|
1252
|
-
# Draw one or more three-dimensional line plots.
|
1257
|
+
# (Plot) Draw one or more three-dimensional line plots.
|
1253
1258
|
def plot3(*args)
|
1254
1259
|
create_plot(:plot3, *args)
|
1255
1260
|
end
|
1256
1261
|
|
1257
|
-
# Draw one or more three-dimensional scatter plots.
|
1262
|
+
# (Plot) Draw one or more three-dimensional scatter plots.
|
1258
1263
|
def scatter3(*args)
|
1259
1264
|
create_plot(:scatter3, *args)
|
1260
1265
|
end
|
1261
1266
|
|
1262
1267
|
alias _shade_ shade
|
1268
|
+
# (Plot)
|
1263
1269
|
def shade(*args)
|
1264
1270
|
create_plot(:shade, *args)
|
1265
1271
|
end
|
1266
1272
|
|
1273
|
+
# (Plot)
|
1267
1274
|
def volume(v, kv = {})
|
1268
1275
|
create_plot(:volume, v, kv) do |plt|
|
1269
1276
|
plt.args = [[nil, nil, v, nil, '']]
|
1270
1277
|
end
|
1271
1278
|
end
|
1272
1279
|
|
1273
|
-
# Draw a bar plot.
|
1280
|
+
# (Plot) Draw a bar plot.
|
1274
1281
|
def barplot(labels, heights, kv = {})
|
1275
1282
|
labels = labels.map(&:to_s)
|
1276
1283
|
wc, hc = barcoordinates(heights)
|
@@ -1288,7 +1295,7 @@ module GR
|
|
1288
1295
|
end
|
1289
1296
|
end
|
1290
1297
|
|
1291
|
-
# Draw a histogram.
|
1298
|
+
# (Plot) Draw a histogram.
|
1292
1299
|
def histogram(x, kv = {})
|
1293
1300
|
create_plot(:hist, x, kv) do |plt|
|
1294
1301
|
nbins = plt.kvs[:nbins] || 0
|
@@ -1297,7 +1304,7 @@ module GR
|
|
1297
1304
|
end
|
1298
1305
|
end
|
1299
1306
|
|
1300
|
-
# Draw an image.
|
1307
|
+
# (Plot) Draw an image.
|
1301
1308
|
def imshow(img, kv = {})
|
1302
1309
|
img = Numo::DFloat.cast(img) # Umm...
|
1303
1310
|
create_plot(:imshow, img, kv) do |plt|
|
@@ -1305,7 +1312,7 @@ module GR
|
|
1305
1312
|
end
|
1306
1313
|
end
|
1307
1314
|
|
1308
|
-
# Draw an isosurface.
|
1315
|
+
# (Plot) Draw an isosurface.
|
1309
1316
|
def isosurface(v, kv = {})
|
1310
1317
|
v = Numo::DFloat.cast(v) # Umm...
|
1311
1318
|
create_plot(:isosurface, v, kv) do |plt|
|
@@ -1313,6 +1320,34 @@ module GR
|
|
1313
1320
|
end
|
1314
1321
|
end
|
1315
1322
|
|
1323
|
+
def hold(flag = true)
|
1324
|
+
plt = GR::Plot.last_plot
|
1325
|
+
plt.kvs.slice(:window, :scale, :xaxis, :yaxis, :zaxis).merge({ ax: flag, clear: !flag })
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
# Set current subplot index.
|
1329
|
+
def subplot(nr, nc, p)
|
1330
|
+
xmin = 1
|
1331
|
+
xmax = 0
|
1332
|
+
ymin = 1
|
1333
|
+
ymax = 0
|
1334
|
+
p = [p] if p.is_a? Integer
|
1335
|
+
p.each do |i|
|
1336
|
+
r = (nr - (i - 1) / nc).to_f
|
1337
|
+
c = ((i - 1) % nc + 1).to_f
|
1338
|
+
xmin = [xmin, (c - 1) / nc].min
|
1339
|
+
xmax = [xmax, c / nc].max
|
1340
|
+
ymin = [ymin, (r - 1) / nr].min
|
1341
|
+
ymax = [ymax, r / nr].max
|
1342
|
+
end
|
1343
|
+
{
|
1344
|
+
subplot: [xmin, xmax, ymin, ymax],
|
1345
|
+
clear: p[0] == 1,
|
1346
|
+
update: p[-1] == nr * nc
|
1347
|
+
}
|
1348
|
+
end
|
1349
|
+
|
1350
|
+
# (Plot) Save the current figure to a file.
|
1316
1351
|
def savefig(filename, kv = {})
|
1317
1352
|
GR.beginprint(filename)
|
1318
1353
|
plt = GR::Plot.last_plot
|
@@ -1323,40 +1358,41 @@ module GR
|
|
1323
1358
|
|
1324
1359
|
private
|
1325
1360
|
|
1326
|
-
def create_plot(type, *args
|
1361
|
+
def create_plot(type, *args)
|
1327
1362
|
plt = GR::Plot.new(*args)
|
1328
1363
|
plt.kvs[:kind] = type
|
1329
|
-
|
1364
|
+
yield(plt) if block_given?
|
1330
1365
|
plt.plot_data
|
1331
1366
|
plt
|
1332
1367
|
end
|
1333
1368
|
|
1334
|
-
def
|
1369
|
+
def format_xyzc(*args)
|
1335
1370
|
kv = if args[-1].is_a? Hash
|
1336
1371
|
args.pop
|
1337
1372
|
else
|
1338
1373
|
{}
|
1339
1374
|
end
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1375
|
+
|
1376
|
+
args = [args] unless args.all? do |i|
|
1377
|
+
i.is_a?(Array) && (i[0].is_a?(Array) || narray?(i[0]))
|
1378
|
+
end
|
1379
|
+
args.map! do |xyzc|
|
1380
|
+
if xyzc.size == 1
|
1381
|
+
if xyzc[0].is_a? Array
|
1382
|
+
z = Numo::DFloat.cast(xyzc[0])
|
1383
|
+
elsif narray?(xyzc[0])
|
1384
|
+
z = xyzc[0]
|
1385
|
+
end
|
1386
|
+
xsize, ysize = z.shape
|
1387
|
+
x = (1..ysize).to_a * xsize
|
1388
|
+
y = (1..xsize).map { |i| Array.new(ysize, i) }.flatten
|
1389
|
+
[x, y, z]
|
1390
|
+
else
|
1391
|
+
|
1392
|
+
xyzc
|
1345
1393
|
end
|
1346
|
-
xsize, ysize = z.shape
|
1347
|
-
# NOTE:
|
1348
|
-
# See
|
1349
|
-
# https://github.com/jheinen/GR.jl/pull/246
|
1350
|
-
# https://github.com/jheinen/GR.jl/issues/241
|
1351
|
-
x = (1..ysize).to_a * xsize
|
1352
|
-
y = (1..xsize).map { |i| Array.new(ysize, i) }.flatten
|
1353
|
-
|
1354
|
-
elsif args.size == 3
|
1355
|
-
x, y, z = args
|
1356
|
-
else
|
1357
|
-
raise
|
1358
1394
|
end
|
1359
|
-
[
|
1395
|
+
[*args, kv]
|
1360
1396
|
end
|
1361
1397
|
|
1362
1398
|
def hist(x, nbins = 0)
|