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 +4 -4
- data/README.md +112 -37
- data/lib/gr.rb +66 -24
- data/lib/gr/plot.rb +158 -124
- data/lib/gr3.rb +9 -16
- data/lib/gr_commons/fiddley.rb +1 -1
- data/lib/gr_commons/gr_commons.rb +4 -0
- data/lib/gr_commons/search_shared_library.rb +73 -0
- data/lib/gr_commons/version.rb +1 -1
- data/lib/grm.rb +52 -0
- data/lib/grm/ffi.rb +73 -0
- data/lib/grm/grmbase.rb +13 -0
- data/lib/grm/version.rb +5 -0
- metadata +40 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25cf22ddd78bcfc66e0feb206821fe40d193b972ee7ed0512ae29b7ed3feaf57
|
4
|
+
data.tar.gz: 273b62f5cd998231148923f09749b8aed2117da8bc2dae1773b6e6cb537b151d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1d8c8f88277e83cdde72bee429fc9b1a8bc4b2b2d976f4dfea4d423465d5e4da0b8b948fb00fc6ed44b518b6658077f1596c2763b514bf51ab60973a9ffddbe
|
7
|
+
data.tar.gz: a1fe8ab99fc491ae99c9e4245bb0226518898f2655c0dff9b616ce98ce0ddd7a322778b3e2bd48d38144676947823f5390d6ce9e8d18efe175b5920d218802f5
|
data/README.md
CHANGED
@@ -6,31 +6,43 @@
|
|
6
6
|
[](https://gitter.im/red-data-tools/en)
|
7
7
|
[](https://rubydoc.info/gems/ruby-gr)
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
[](examples/rdatasets.rb)
|
10
|
+
[](examples/fast_plots.rb)
|
11
|
+
[](examples/fast_plots.rb)
|
12
|
+
[](examples/fast_plots.rb)
|
13
|
+
[](examples/fast_plots.rb)
|
14
|
+
[](examples/fast_plots.rb)
|
15
|
+
[](examples/griddata.rb)
|
16
|
+
[](examples/2darray.rb)
|
17
|
+
[](examples/2dpolararray.rb)
|
18
|
+
[](examples/hexbin.rb)
|
19
|
+
[](examples/rdatasets.rb)
|
20
|
+
[](examples/rdatasets.rb)
|
21
|
+
[](examples/kws2.rb)
|
22
|
+
[](examples/face.rb)
|
23
|
+
[](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.
|
18
|
-
|
19
|
-
[Install GR](#gr-installation).
|
29
|
+
GR.rb supports Ruby 2.5+.
|
20
30
|
|
21
|
-
|
31
|
+
First, [install GR](#gr-installation). Then install `ruby-gr` gem.
|
22
32
|
|
23
33
|
```sh
|
24
|
-
|
34
|
+
gem install ruby-gr
|
25
35
|
```
|
26
36
|
|
27
|
-
|
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
|
-
|
42
|
+
export GRDIR="/your/path/to/gr"
|
31
43
|
```
|
32
44
|
|
33
|
-
|
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
|
-
|
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
|
-
|
53
|
-
|
86
|
+
```ruby
|
87
|
+
GR.savefig("figure.png")
|
88
|
+
```
|
54
89
|
|
55
|
-
##
|
90
|
+
## API Overview
|
56
91
|
|
57
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
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
|
-
###
|
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
|
-
###
|
170
|
+
### Using package managers
|
99
171
|
|
100
|
-
|
101
|
-
|
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
|
-
|
176
|
+
#### Mac - Homebrew
|
105
177
|
|
106
178
|
```sh
|
107
|
-
|
179
|
+
brew install libgr
|
108
180
|
```
|
109
181
|
|
110
|
-
|
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
|
-
###
|
186
|
+
### Windows - MSYS2
|
113
187
|
|
114
|
-
|
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
|
-
*
|
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
|
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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
#
|
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(
|
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(
|
1643
|
+
tri = tri.each_slice(dim).to_a
|
1602
1644
|
[n_tri, tri]
|
1603
1645
|
else
|
1604
1646
|
0
|
data/lib/gr/plot.rb
CHANGED
@@ -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
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
118
|
-
viewport
|
119
|
-
|
120
|
-
|
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
|
137
|
+
GR.setviewport(*viewport)
|
135
138
|
|
136
139
|
kvs[:viewport] = viewport
|
137
|
-
kvs[:vp]
|
138
|
-
kvs[: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
|
169
|
-
scale |= GR::OPTION_Y_LOG
|
170
|
-
scale |= GR::OPTION_Z_LOG
|
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 (
|
193
|
-
xmin
|
194
|
-
|
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
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
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
|
212
|
-
ymin
|
222
|
+
if %i[heatmap polarheatmap].include?(kind) && kvs.has_key?(:ylim)
|
223
|
+
ymin -= 0.5
|
224
|
+
ymax += 0.5
|
213
225
|
end
|
214
|
-
if
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
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
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
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
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
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
|
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]
|
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
|
-
|
297
|
-
|
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.
|
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.
|
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
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
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
|
-
|
690
|
-
|
691
|
-
|
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) }
|
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
|
-
|
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
|
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
|
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(
|
1300
|
-
create_plot(:hist,
|
1328
|
+
def histogram(series, kv = {})
|
1329
|
+
create_plot(:hist, series, kv) do |plt|
|
1301
1330
|
nbins = plt.kvs[:nbins] || 0
|
1302
|
-
x, y = hist(
|
1303
|
-
plt.args = [
|
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.
|