ruby-gr 0.0.18 → 0.0.23

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46a782911565b4128622399489e47d79e7ced0d3880d9c5c5adacdae7fa24709
4
- data.tar.gz: e89d9c7e5a5ae0bf53352f3afb71fd1206c9a0e7aa5a3ba83504457fa5689b7d
3
+ metadata.gz: 25cf22ddd78bcfc66e0feb206821fe40d193b972ee7ed0512ae29b7ed3feaf57
4
+ data.tar.gz: 273b62f5cd998231148923f09749b8aed2117da8bc2dae1773b6e6cb537b151d
5
5
  SHA512:
6
- metadata.gz: 21a8aeb6c49da80f87bb764ba149ffa8c7e7bffa3ed171002d1c6963537b9f0b500a96f77eac6876c8c3a8af9601aad6c8a79dfd4e0aea6d7d356adfc59b04db
7
- data.tar.gz: 99a2e4204e8eef936979895183d86003860e2b9b356a24bc0f132793177459fa8fc782cf8bdd4ac4c2a29fca6e77aff41d7501123e84917172009bc5b5907547
6
+ metadata.gz: d1d8c8f88277e83cdde72bee429fc9b1a8bc4b2b2d976f4dfea4d423465d5e4da0b8b948fb00fc6ed44b518b6658077f1596c2763b514bf51ab60973a9ffddbe
7
+ data.tar.gz: a1fe8ab99fc491ae99c9e4245bb0226518898f2655c0dff9b616ce98ce0ddd7a322778b3e2bd48d38144676947823f5390d6ce9e8d18efe175b5920d218802f5
data/README.md CHANGED
@@ -6,31 +6,43 @@
6
6
  [![Gitter Chat](https://badges.gitter.im/red-data-tools/en.svg)](https://gitter.im/red-data-tools/en)
7
7
  [![Docs Latest](https://img.shields.io/badge/docs-latest-blue.svg)](https://rubydoc.info/gems/ruby-gr)
8
8
 
9
- <p align="center">
10
- <img src="https://user-images.githubusercontent.com/5798442/70857099-13d57600-1f2c-11ea-8f3c-7d81065f13a5.png">
11
- </p>
12
-
13
- :bar_chart: [GR framework](https://github.com/sciapp/gr) - the graphics library for visualization - for Ruby
9
+ [![rdatasets-1](https://i.imgur.com/XEQ6wKs.png)](examples/rdatasets.rb)
10
+ [![stem](https://i.imgur.com/3w0Ejrm.png)](examples/fast_plots.rb)
11
+ [![histogram](https://i.imgur.com/xUdoA2s.png)](examples/fast_plots.rb)
12
+ [![barplot](https://i.imgur.com/52bOFKE.png)](examples/fast_plots.rb)
13
+ [![scatter3](https://i.imgur.com/yTTVetQ.png)](examples/fast_plots.rb)
14
+ [![volume](https://i.imgur.com/CuRN6oC.png)](examples/fast_plots.rb)
15
+ [![griddata](https://i.imgur.com/58HdYDo.png)](examples/griddata.rb)
16
+ [![2darray](https://i.imgur.com/aKR2FJG.png)](examples/2darray.rb)
17
+ [![2dpolararray](https://i.imgur.com/cmSrxvS.png)](examples/2dpolararray.rb)
18
+ [![hexbin](https://i.imgur.com/unWhQHr.png)](examples/hexbin.rb)
19
+ [![rdatasets-2](https://i.imgur.com/ZPit2F5.png)](examples/rdatasets.rb)
20
+ [![rdatasets-3](https://i.imgur.com/TbNoxwy.png)](examples/rdatasets.rb)
21
+ [![surface](https://i.imgur.com/sWdaHme.png)](examples/kws2.rb)
22
+ [![face](https://i.imgur.com/uLCKi2r.png)](examples/face.rb)
23
+ [![shade](https://i.imgur.com/VJmS3EQ.png)](examples/shade_ex.rb)
24
+
25
+ :bar_chart: [GR framework](https://github.com/sciapp/gr) - powerful visualization library - for Ruby
14
26
 
15
27
  ## Installation
16
28
 
17
- GR.rb supports Ruby 2.4+.
18
-
19
- [Install GR](#gr-installation).
29
+ GR.rb supports Ruby 2.5+.
20
30
 
21
- Set environment variable GRDIR, if you have not already done.
31
+ First, [install GR](#gr-installation). Then install `ruby-gr` gem.
22
32
 
23
33
  ```sh
24
- export GRDIR="/your/path/to/gr"
34
+ gem install ruby-gr
25
35
  ```
26
36
 
27
- Add this line to your application's Gemfile:
37
+ Note: If you are using Rubyinstaller(Windows), pacman will automatically install [mingw-w64-gr](https://packages.msys2.org/base/mingw-w64-gr).
38
+
39
+ Set environment variable `GRDIR`.
28
40
 
29
41
  ```sh
30
- gem 'ruby-gr'
42
+ export GRDIR="/your/path/to/gr"
31
43
  ```
32
44
 
33
- GR3 and GR::Plot require [numo-narray](https://github.com/ruby-numo/numo-narray).
45
+ Note: If you use package managers to install GR, [pkg-config](https://github.com/ruby-gnome/pkg-config) may automatically detect the shared library location without specifying the `GRDIR` environment variable.
34
46
 
35
47
  ## Quick Start
36
48
 
@@ -47,43 +59,103 @@ y = [0.3, 0.5, 0.4, 0.2, 0.6, 0.7]
47
59
  GR.plot(x, y)
48
60
  ```
49
61
 
50
- ## Examples
62
+ <p align="center">
63
+ <img src="https://user-images.githubusercontent.com/5798442/84570709-242ab880-adca-11ea-9099-3a6b3418bf19.png">
64
+ </p>
65
+
66
+ ```ruby
67
+ require 'gr/plot'
68
+
69
+ x = Numo::DFloat.linspace(0, 10, 101)
70
+ y1 = Numo::NMath.sin(x)
71
+ y2 = Numo::NMath.cos(x)
72
+
73
+ GR.plot(
74
+ [x, y1, 'bo'], [x, y2, 'g*'],
75
+ title: "Multiple plot example",
76
+ xlabel: "x",
77
+ ylabel: "y",
78
+ ylim: [-1.2, 1.2],
79
+ labels: ["sin(x)", "cos(x)"],
80
+ location: 11
81
+ )
82
+ ```
83
+
84
+ Save in PNG format.
51
85
 
52
- Have a look in the [`examples`](https://github.com/red-data-tools/GR.rb/tree/master/examples) directory.
53
- * [Example Gallery](https://github.com/red-data-tools/GR.rb/wiki/1.-Example-gallery)
86
+ ```ruby
87
+ GR.savefig("figure.png")
88
+ ```
54
89
 
55
- ## Features
90
+ ## API Overview
56
91
 
57
- #### GR::Plot
92
+ There are two different approaches to plotting with GR.rb. One way is to call Matlab-like APIs. The other is to call GR/GR3 native functions. We are planning to prepare a [more object-oriented interface](https://github.com/kojix2/GRUtils.rb) based on [GRUtils.jl](https://github.com/heliosdrm/GRUtils.jl) in the future.
58
93
 
59
- A simple, matlab-style API.
94
+ #### GR::Plot - A simple, matlab-style API.
60
95
 
61
96
  ```ruby
62
97
  require 'gr/plot'
98
+ GR.plot(x, y)
63
99
  ```
64
100
 
65
- `plot` `step` `scatter` `stem` `histogram` `contour` `contourf` `hexbin` `heatmap` `wireframe` `surface` `plot3` `scatter3` `imshow` `isosurface` `polar` `polarhist` `polarheatmap` `trisurf` `tricont` `shade` `volume`
66
-
67
- #### GR
101
+ List of vailable functions. See [GR.rb Wiki](https://github.com/red-data-tools/GR.rb/wiki) for details.
102
+
103
+ [`plot`](../../wiki/Plotting-functions#plot)
104
+ [`step`](../../wiki/Plotting-functions#step)
105
+ [`plot3`](../../wiki/Plotting-functions#plot3)
106
+ [`polar`](../../wiki/Plotting-functions#polar)
107
+ [`scatter`](../../wiki/Plotting-functions#scatter)
108
+ [`scatter3`](../../wiki/Plotting-functions#scatter3)
109
+ [`stem`](../../wiki/Plotting-functions#stem)
110
+ [`barplot`](../../wiki/Plotting-functions#barplot)
111
+ [`histogram`](../../wiki/Plotting-functions#histogram)
112
+ [`polarhistogram`](../../wiki/Plotting-functions#polarhistogram)
113
+ [`hexbin`](../../wiki/Plotting-functions#hexbin)
114
+ [`contour`](../../wiki/Plotting-functions#contour)
115
+ [`contourf`](../../wiki/Plotting-functions#contourf)
116
+ [`tricont`](../../wiki/Plotting-functions#tricont)
117
+ [`surface`](../../wiki/Plotting-functions#surface)
118
+ [`trisurf`](../../wiki/Plotting-functions#trisurf)
119
+ [`wireframe`](../../wiki/Plotting-functions#wireframe)
120
+ [`volume`](../../wiki/Plotting-functions#volume)
121
+ [`heatmap`](../../wiki/Plotting-functions#heatmap)
122
+ [`polarheatmap`](../../wiki/Plotting-functions#polarheatmap)
123
+ [`shade`](../../wiki/Plotting-functions#shade)
124
+ [`imshow`](../../wiki/Plotting-functions#imshow)
125
+ [`isosurface`](../../wiki/Plotting-functions#isosurface)
126
+
127
+ #### GR - A module for calling native GR functions.
128
+
129
+ 2-D Plots and common 3-D Plots.
68
130
 
69
131
  ```ruby
70
132
  require 'gr'
133
+
134
+ # For example
135
+ GR.setviewport(0.1, 0.9, 0.1, 0.9)
136
+ GR.setwindow(0.0, 20.0, 0.0, 20.0)
71
137
  ```
72
138
 
73
- #### GR3
139
+ #### GR3 - A module for calling native GR3 functions.
140
+
141
+ Complex 3D scenes.
74
142
 
75
143
  ```ruby
76
144
  require 'gr3'
145
+
146
+ # For example
147
+ GR3.cameralookat(-3, 2, -2, 0, 0, 0, 0, 0, -1)
77
148
  ```
78
149
 
79
150
  ## Documentation
80
151
 
152
+ - [GR.rb Wiki](https://github.com/red-data-tools/GR.rb/wiki)
81
153
  - [GR Framework](https://gr-framework.org/)
82
154
  - [GR.rb API Documentation](https://rubydoc.info/gems/ruby-gr)
83
155
 
84
156
  ## GR Installation
85
157
 
86
- ### Official binary release
158
+ ### Installing an official release (recommended)
87
159
 
88
160
  Download the [latest release](https://github.com/sciapp/gr/releases).
89
161
 
@@ -95,23 +167,25 @@ export GRDIR="your/path/to/gr"
95
167
 
96
168
  * macOS Catalina and macOS Mojave: See the "How to open an app that hasn’t been notarized or is from an unidentified developer" section of [Safely open apps on your Mac](https://support.apple.com/en-us/HT202491) in the Apple documentation.
97
169
 
98
- ### Homebrew
170
+ ### Using package managers
99
171
 
100
- ```sh
101
- brew install libgr
102
- ```
172
+ * The third party GR packages for Mac, Linux and Windows are available (for advanced users).
173
+ * If you find any problem, please report the issue [here](https://github.com/red-data-tools/GR.rb/issues).
174
+ * Note: These packages may not have some features, for example, video output.
103
175
 
104
- Set environment variable GRDIR.
176
+ #### Mac - Homebrew
105
177
 
106
178
  ```sh
107
- export GRDIR=$(brew --prefix libgr)
179
+ brew install libgr
108
180
  ```
109
181
 
110
- If you fail to build libgr using homebrew, Please feel free to [send us your feedback](https://github.com/red-data-tools/GR.rb/issues).
182
+ #### Linux - APT Yum
183
+
184
+ [packages.red-data-tools.org](https://github.com/red-data-tools/packages.red-data-tools.org) provides `libgr-dev`, `libgr3-dev` and `libgrm-dev`
111
185
 
112
- ### Red data tools repository
186
+ ### Windows - MSYS2
113
187
 
114
- Red data tools provides [packages](https://github.com/red-data-tools/packages.red-data-tools.org ) related to our project including `libgr-dev` and `libgr3-dev` for advanced users.
188
+ If you are using Rubyinstaller, pacman will automatically install [mingw-w64-gr](https://packages.msys2.org/base/mingw-w64-gr) when the gem is installed.
115
189
 
116
190
  ## Backend for Charty
117
191
 
@@ -119,13 +193,14 @@ GR.rb will be the default backend for [Charty](https://github.com/red-data-tools
119
193
 
120
194
  ## Contributing
121
195
 
122
- * Report bugs
123
- * Fix bugs and submit pull requests
196
+ * [Report bugs](https://github.com/red-data-tools/GR.rb/issues)
197
+ * Fix bugs and [submit pull requests](https://github.com/red-data-tools/GR.rb/pulls)
124
198
  * Write, clarify, or fix documentation
125
199
  * Suggest or add new features
126
- * Create visualization library based on GR.rb
200
+ * Update GR packages ( Homebrew, MinGW, red-data-tools )
201
+ * Create visualization tools based on GR.rb
127
202
 
128
203
  ## Acknowledgements
129
204
 
130
- We would like to thank Josef Heinen, the creator of [GR.jl](https://github.com/jheinen/GR.jl), Florian Rhiem, the creator of [python-gr](https://github.com/sciapp/python-gr), and [GR](https://github.com/sciapp/gr) developers.
205
+ We would like to thank Josef Heinen, the creator of [GR](https://github.com/sciapp/gr) and [GR.jl](https://github.com/jheinen/GR.jl), Florian Rhiem, the creator of [python-gr](https://github.com/sciapp/python-gr), and all [GR](https://github.com/sciapp/gr) developers.
131
206
 
data/lib/gr.rb CHANGED
@@ -52,27 +52,20 @@ module GR
52
52
  attr_accessor :ffi_lib
53
53
  end
54
54
 
55
+ require_relative 'gr_commons/gr_commons'
56
+ extend GRCommons::SearchSharedLibrary
57
+
55
58
  # Platforms | path
56
59
  # Windows | bin/libgr.dll
57
60
  # MacOSX | lib/libGR.so (NOT .dylib)
58
61
  # Ubuntu | lib/libGR.so
59
- if Object.const_defined?(:RubyInstaller)
60
- ENV['GRDIR'] ||= [
61
- RubyInstaller::Runtime.msys2_installation.msys_path,
62
- RubyInstaller::Runtime.msys2_installation.mingwarch
63
- ].join(File::ALT_SEPARATOR)
64
- self.ffi_lib = File.expand_path('bin/libgr.dll', ENV['GRDIR'])
65
- RubyInstaller::Runtime.add_dll_directory(File.dirname(ffi_lib))
66
- else
67
- raise Error, 'Please set env variable GRDIR' unless ENV['GRDIR']
68
-
69
- self.ffi_lib = File.expand_path('lib/libGR.so', ENV['GRDIR'])
70
- end
62
+ self.ffi_lib = case RbConfig::CONFIG['host_os']
63
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
64
+ search_shared_library('libgr.dll', 'gr')
65
+ else
66
+ search_shared_library('libGR.so', 'gr')
67
+ end
71
68
 
72
- # Change the default encoding to UTF-8.
73
- ENV['GKS_ENCODING'] ||= 'utf8'
74
-
75
- require_relative 'gr_commons/gr_commons'
76
69
  require_relative 'gr/version'
77
70
  require_relative 'gr/ffi'
78
71
  require_relative 'gr/grbase'
@@ -103,7 +96,12 @@ module GR
103
96
  super
104
97
  end
105
98
 
106
- # inqdspsize
99
+ # Get the current display size.
100
+ # Depending on the current workstation type, the current display might be
101
+ # the primary screen (e.g. when using gksqt or GKSTerm) or a purely virtual
102
+ # display (e.g. when using Cairo). When a high DPI screen is used as the
103
+ # current display, width and height will be in logical pixels.
104
+ # @return [Array] meter_width, meter_height, width, height
107
105
  def inqdspsize
108
106
  inquiry %i[double double int int] do |*pts|
109
107
  super(*pts)
@@ -115,9 +113,7 @@ module GR
115
113
  # @param connection [String] A connection identifier.
116
114
  # @param workstation_type [Integer] The desired workstation type.
117
115
  # * 5 : Workstation Independent Segment Storage
118
- # * 7, 8 : Computer Graphics Metafile (CGM binary, clear text)
119
116
  # * 41 : Windows GDI
120
- # * 51 : Mac Quickdraw
121
117
  # * 61 - 64 : PostScript (b/w, color)
122
118
  # * 101, 102 : Portable Document Format (plain, compressed)
123
119
  # * 210 - 213 : X Windows
@@ -138,7 +134,6 @@ module GR
138
134
  # * 410 : Socket driver
139
135
  # * 415 : 0MQ driver
140
136
  # * 420 : OpenGL
141
- # * 430 : HTML5 Canvas
142
137
  def openws(*)
143
138
  super
144
139
  end
@@ -161,6 +156,7 @@ module GR
161
156
  super
162
157
  end
163
158
 
159
+ # Configure the specified workstation.
164
160
  def configurews(*)
165
161
  super
166
162
  end
@@ -302,6 +298,7 @@ module GR
302
298
  super(n, x, y, m, method)
303
299
  end
304
300
 
301
+ # Interpolate data from arbitrary points at points on a rectangular grid.
305
302
  def gridit(xd, yd, zd, nx, ny)
306
303
  nd = equal_length(xd, yd, zd)
307
304
  inquiry [{ double: nx }, { double: ny }, { double: nx * ny }] do |px, py, pz|
@@ -363,7 +360,6 @@ module GR
363
360
  super
364
361
  end
365
362
 
366
- # inqlinecolorind
367
363
  def inqlinecolorind
368
364
  inquiry_int { |pt| super(pt) }
369
365
  end
@@ -509,6 +505,8 @@ module GR
509
505
  # * 129 : FONT_PALATINO_BOLDITALIC
510
506
  # * 130 : FONT_ZAPFCHANCERY_MEDIUMITALIC
511
507
  # * 131 : FONT_ZAPFDINGBATS
508
+ # * 232 : FONT_COMPUTERMODERN
509
+ # * 233 : FONT_DEJAVUSANS
512
510
  # @param precision [Integer] Text precision
513
511
  # * 0 : TEXT_PRECISION_STRING
514
512
  # * String precision (higher quality)
@@ -516,10 +514,14 @@ module GR
516
514
  # * Character precision (medium quality)
517
515
  # * 2 : TEXT_PRECISION_STROKE
518
516
  # * Stroke precision (lower quality)
517
+ # * 3 : TEXT_PRECISION_OUTLINE
518
+ # * Outline precision (highest quality)
519
519
  # The appearance of a font depends on the text precision value specified.
520
520
  # STRING, CHARACTER or STROKE precision allows for a greater or lesser
521
521
  # realization of the text primitives, for efficiency. STRING is the default
522
- # precision for GR and produces the highest quality output.
522
+ # precision for GR and produces the highest quality output using either
523
+ # native font rendering or FreeType. OUTLINE uses the GR path rendering
524
+ # functions to draw individual glyphs and produces the highest quality output.
523
525
  def settextfontprec(*)
524
526
  super
525
527
  end
@@ -561,6 +563,14 @@ module GR
561
563
  super
562
564
  end
563
565
 
566
+ # Gets the current character height.
567
+ # This function gets the height of text output primitives. Text height is
568
+ # defined as a percentage of the default window. GR uses the default text
569
+ # height of 0.027 (2.7% of the height of the default window).
570
+ def inqcharheight
571
+ inquiry_double { |pt| super(pt) }
572
+ end
573
+
564
574
  # Set the current character text angle up vector.
565
575
  # @param ux [Numeric] Text up vector
566
576
  # @param uy [Numeric] Text up vector
@@ -622,6 +632,8 @@ module GR
622
632
  # * Fill the interior of the polygon using the style index as a pattern index
623
633
  # * 3 : HATCH
624
634
  # * Fill the interior of the polygon using the style index as a cross-hatched style
635
+ # * 4 : SOLID_WITH_BORDER
636
+ # * Fill the interior of the polygon using the fill color index and draw the bounding polyline
625
637
  # `setfillintstyle` defines the interior style for subsequent fill area output
626
638
  # primitives. The default interior style is HOLLOW.
627
639
  def setfillintstyle(*)
@@ -645,6 +657,7 @@ module GR
645
657
  end
646
658
 
647
659
  # Returns the current fill area color index.
660
+ # This function gets the color index for PATTERN and HATCH fills.
648
661
  def inqfillstyle
649
662
  inquiry_int { |pt| super(pt) }
650
663
  end
@@ -658,6 +671,7 @@ module GR
658
671
  end
659
672
 
660
673
  # Returns the current fill area color index.
674
+ # This function gets the color of fill area output primitives.
661
675
  def inqfillcolorind
662
676
  inquiry_int { |pt| super(pt) }
663
677
  end
@@ -932,12 +946,40 @@ module GR
932
946
  # coordinate unit. Major tick marks are twice as long as minor tick marks.
933
947
  # A negative value reverses the tick marks on the axes from inward facing
934
948
  # to outward facing (or vice versa).
949
+ # Tick marks are positioned along each axis so that major tick marks fall on
950
+ # the axes origin (whether visible or not). Major tick marks are labeled
951
+ # with the corresponding data values. Axes are drawn according to the scale
952
+ # of the window. Axes and tick marks are drawn using solid lines; line color
953
+ # and width can be modified using the gr_setlinetype and gr_setlinewidth
954
+ # functions. Axes are drawn according to the linear or logarithmic
955
+ # transformation established by the gr_setscale function.
935
956
  def axes(*)
936
957
  super
937
958
  end
938
959
 
939
960
  alias axes2d axes
940
961
 
962
+ # Create axes in the current workspace and supply a custom function for
963
+ # changing the behaviour of the tick labels.
964
+ # @param x_tick [Numeric] The interval between minor tick marks on the X axis.
965
+ # @param y_tick [Numeric] The interval between minor tick marks on the Y axis.
966
+ # @param x_org [Numeric] The world coordinate of the origin (point of intersection) of the X axis.
967
+ # @param y_org [Numeric] The world coordinate of the origin (point of intersection) of the Y axis.
968
+ # @param major_x [Integer] Unitless integer value specifying the number of minor tick intervals between major tick marks on the X axis. Values of 0 or 1 imply no minor ticks. Negative values specify no labels will be drawn for the associated axis.
969
+ # @param major_y [Integer] Unitless integer value specifying the number of minor tick intervals between major tick marks on the Y axis. Values of 0 or 1 imply no minor ticks. Negative values specify no labels will be drawn for the associated axis.
970
+ # @param tick_size [Numeric] The length of minor tick marks specified in a normalized device coordinate unit. Major tick marks are twice as long as minor tick marks. A negative value reverses the tick marks on the axes from inward facing to outward facing (or vice versa).
971
+ # @param fpx [Pointer] Function pointer to a function that returns a label for a given tick on the X axis. The callback function should have the following arguments [Numeric]
972
+ # @param fpy [Pointer] Exactly same as the fpx above, but for the the Y axis.
973
+ # Similar to gr_axes() but allows more fine-grained control over tick labels
974
+ # and text positioning by supplying callback functions. Within the callback
975
+ # function you can use normal GR text primitives for performing any
976
+ # manipulations on the label text.
977
+ # See gr_axes() for more details on drawing axes.
978
+ # * fpx/fpy
979
+ # * param x [Numeric] NDC of the label in X direction.
980
+ # * param y [Numeric] NDC of the label in Y direction.
981
+ # * param svalue [String] Internal string representation of the text drawn by GR at (x,y).
982
+ # * param value [Numeric] Floating point representation of the label drawn at (x,y).
941
983
  def axeslbl(*)
942
984
  super
943
985
  end
@@ -1595,10 +1637,10 @@ module GR
1595
1637
  super(npoints, x, y, ntri, triangles.ref)
1596
1638
  end
1597
1639
  if n_tri > 0
1598
- tri = triangles.to_str(3 * n_tri * Fiddle::SIZEOF_INT).unpack('l*') # Int32
1640
+ tri = triangles.to_str(dim * n_tri * Fiddle::SIZEOF_INT).unpack('l*') # Int32
1599
1641
  # Ruby : 0-based indexing
1600
1642
  # Julia : 1-based indexing
1601
- tri = tri.each_slice(3).to_a
1643
+ tri = tri.each_slice(dim).to_a
1602
1644
  [n_tri, tri]
1603
1645
  else
1604
1646
  0
@@ -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)
@@ -564,7 +577,9 @@ module GR
564
577
  # Not yet.
565
578
  end
566
579
 
567
- 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
568
583
 
569
584
  set_viewport(kind, kvs[:subplot])
570
585
  unless kvs[:ax]
@@ -632,8 +647,7 @@ module GR
632
647
  if z || c
633
648
  if c
634
649
  cmin, cmax = kvs[:crange]
635
- c = c.to_a if narray?(c)
636
- c.map! { |i| normalize_color(i, cmin, cmax) }
650
+ c = c.map { |i| normalize_color(i, cmin, cmax) }
637
651
  cind = c.map { |i| (1000 + i * 255).round }
638
652
  end
639
653
  x.length.times do |i|
@@ -658,14 +672,26 @@ module GR
658
672
  GR.polymarker(x, y)
659
673
 
660
674
  when :hist
661
- ymin = kvs[:window][2]
662
- y.length.times do |i|
663
- GR.setfillcolorind(989)
664
- GR.setfillintstyle(GR::INTSTYLE_SOLID)
665
- GR.fillrect(x[i], x[i + 1], ymin, y[i])
666
- GR.setfillcolorind(1)
667
- GR.setfillintstyle(GR::INTSTYLE_HOLLOW)
668
- 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
669
695
  end
670
696
 
671
697
  when :polarhist
@@ -686,9 +712,10 @@ module GR
686
712
  cmap = colormap
687
713
  cmin, cmax = kvs[:zrange]
688
714
  data = z.map { |i| normalize_color(i, cmin, cmax) }
689
- colors = data.map { |i| 1000 + i * 255 }
690
- # if kvs[:xflip]
691
- # 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
692
719
  GR.polarcellarray(0, 0, 0, 360, 0, 1, w, h, colors)
693
720
  draw_polar_axes
694
721
  kvs[:zrange] = [cmin, cmax]
@@ -812,7 +839,7 @@ module GR
812
839
  GR.setmarkertype(GR::MARKERTYPE_SOLID_CIRCLE)
813
840
  if c
814
841
  cmin, cmax = kvs[:crange]
815
- c = c.map { |i| normalize_color(i, cmin, cmax) } # NArray -> Array
842
+ c = c.map { |i| normalize_color(i, cmin, cmax) }
816
843
  cind = c.map { |i| (1000 + i * 255).round }
817
844
  x.length.times do |i|
818
845
  GR.setmarkercolorind(cind[i])
@@ -1018,7 +1045,9 @@ module GR
1018
1045
 
1019
1046
  # Normalize a color c with the range [cmin, cmax]
1020
1047
  # 0 <= normalize_color(c, cmin, cmax) <= 1
1048
+ # Note: narray.map{|i| normalize_color(i)} There's room for speedup.
1021
1049
  def normalize_color(c, cmin, cmax)
1050
+ c = c.to_f # if c is Integer
1022
1051
  c = c.clamp(cmin, cmax) - cmin
1023
1052
  c /= (cmax - cmin) if cmin != cmax
1024
1053
  c
@@ -1059,7 +1088,8 @@ module GR
1059
1088
  args.each do |x, y, z, c|
1060
1089
  if x
1061
1090
  if scale & GR::OPTION_X_LOG != 0
1062
- x.map! { |v| v > 0 ? v : Float::NAN }
1091
+ # duck typing for NArray
1092
+ x = x.map { |v| v > 0 ? v : Float::NAN }
1063
1093
  end
1064
1094
  x0, x1 = x.minmax
1065
1095
  xmin = [x0, xmin].min
@@ -1070,7 +1100,7 @@ module GR
1070
1100
  end
1071
1101
  if y
1072
1102
  if scale & GR::OPTION_Y_LOG != 0
1073
- y.map! { |v| v > 0 ? v : Float::NAN }
1103
+ y = y.map { |v| v > 0 ? v : Float::NAN }
1074
1104
  end
1075
1105
  y0, y1 = y.minmax
1076
1106
  ymin = [y0, ymin].min
@@ -1081,7 +1111,7 @@ module GR
1081
1111
  end
1082
1112
  if z
1083
1113
  if scale & GR::OPTION_Z_LOG != 0
1084
- z.map! { |v| v > 0 ? v : Float::NAN }
1114
+ z = z.map { |v| v > 0 ? v : Float::NAN }
1085
1115
  end
1086
1116
  z0, z1 = z.minmax
1087
1117
  zmin = [z0, zmin].min
@@ -1281,9 +1311,8 @@ module GR
1281
1311
  def barplot(labels, heights, kv = {})
1282
1312
  labels = labels.map(&:to_s)
1283
1313
  wc, hc = barcoordinates(heights)
1284
- horizontal = kv[:horizontal] || false
1285
1314
  create_plot(:bar, labels, heights, kv) do |plt|
1286
- if horizontal
1315
+ if kv[:horizontal]
1287
1316
  plt.args = [[hc, wc, nil, nil, '']]
1288
1317
  plt.kvs[:yticks] = [1, 1]
1289
1318
  plt.kvs[:yticklabels] = labels
@@ -1296,11 +1325,15 @@ module GR
1296
1325
  end
1297
1326
 
1298
1327
  # (Plot) Draw a histogram.
1299
- def histogram(x, kv = {})
1300
- create_plot(:hist, x, kv) do |plt|
1328
+ def histogram(series, kv = {})
1329
+ create_plot(:hist, series, kv) do |plt|
1301
1330
  nbins = plt.kvs[:nbins] || 0
1302
- x, y = hist(x, nbins)
1303
- 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
1304
1337
  end
1305
1338
  end
1306
1339
 
@@ -1326,7 +1359,7 @@ module GR
1326
1359
  end
1327
1360
 
1328
1361
  # Set current subplot index.
1329
- def subplot(nr, nc, p)
1362
+ def subplot(nr, nc, p, kv = {})
1330
1363
  xmin = 1
1331
1364
  xmax = 0
1332
1365
  ymin = 1
@@ -1342,9 +1375,10 @@ module GR
1342
1375
  end
1343
1376
  {
1344
1377
  subplot: [xmin, xmax, ymin, ymax],
1378
+ # The policy of clearing when p[0]==1 is controversial
1345
1379
  clear: p[0] == 1,
1346
1380
  update: p[-1] == nr * nc
1347
- }
1381
+ }.merge kv
1348
1382
  end
1349
1383
 
1350
1384
  # (Plot) Save the current figure to a file.