rust 0.4 → 0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ self_path = File.expand_path(__FILE__)
2
+ Dir.glob(File.dirname(self_path) + "/*.rb").each do |lib|
3
+ require_relative lib unless lib == self_path
4
+ end
@@ -0,0 +1,143 @@
1
+ require_relative 'core'
2
+
3
+ module Rust::Plots
4
+
5
+ ##
6
+ # Allows to create one or many scatter plots.
7
+
8
+ class ScatterPlot < BasePlot
9
+
10
+ ##
11
+ # Creates a new scatter plot, given two arrays of values +x+ and +y+ for the respective axes (optional).
12
+ # +options+ can be specified and directly passed to the plot function in R.
13
+
14
+ def initialize(x = nil, y = nil, **options)
15
+ super()
16
+ @series = []
17
+ if x && y
18
+ self.series(x, y, **options)
19
+ end
20
+ end
21
+
22
+ ##
23
+ # Adds a new data series, given the values for the +x+ and +y+ axes.
24
+ # +options+ can be specified and directly passed to the plot function in R.
25
+
26
+ def series(x, y, **options)
27
+ @series << [x, y, options]
28
+
29
+ return self
30
+ end
31
+
32
+ ##
33
+ # Sets the thickness of the plot lines.
34
+
35
+ def thickness(t)
36
+ self['lwd'] = t
37
+
38
+ return self
39
+ end
40
+
41
+ ##
42
+ # Changes the plot type to lines.
43
+
44
+ def lines()
45
+ self['type'] = "l"
46
+
47
+ return self
48
+ end
49
+
50
+ ##
51
+ # Changes the plot type to points.
52
+
53
+ def points()
54
+ self['type'] = "p"
55
+
56
+ return self
57
+ end
58
+
59
+ ##
60
+ # Changes the plot type to lines and points.
61
+
62
+ def lines_and_points()
63
+ self['type'] = "b"
64
+
65
+ return self
66
+ end
67
+
68
+ protected
69
+ def _show()
70
+ first = true
71
+ palette = self.palette(@series.size)
72
+ i = 0
73
+
74
+ base_options = {}
75
+ unless @options['xlim']
76
+ x_values = @series.map { |v| v[0] }.flatten
77
+ y_values = @series.map { |v| v[1] }.flatten
78
+
79
+ base_options[:xlim] = [x_values.min, x_values.max]
80
+ base_options[:ylim] = [y_values.min, y_values.max]
81
+ end
82
+
83
+ @series.each do |x, y, options|
84
+ options = options.merge(base_options)
85
+ Rust["plotter.x"] = x
86
+ Rust["plotter.y"] = y
87
+
88
+ function = nil
89
+ if first
90
+ function = Rust::Function.new("plot")
91
+ first = false
92
+ else
93
+ function = Rust::Function.new("lines")
94
+ end
95
+
96
+ augmented_options = {}
97
+ augmented_options['col'] = options[:color] || palette[i]
98
+ augmented_options['xlim'] = options[:xlim] if options[:xlim]
99
+ augmented_options['ylim'] = options[:ylim] if options[:ylim]
100
+
101
+ function.options = self._augmented_options(augmented_options)
102
+ function.arguments << Rust::Variable.new("plotter.x")
103
+ function.arguments << Rust::Variable.new("plotter.y")
104
+
105
+ function.call
106
+
107
+ i += 1
108
+ end
109
+
110
+ return self
111
+ end
112
+ end
113
+
114
+ ##
115
+ # Represents a bar plot in R.
116
+
117
+ class BarPlot < BasePlot
118
+
119
+ ##
120
+ # Creates a new bar plot with the given +bars+ values.
121
+
122
+ def initialize(bars)
123
+ super()
124
+ @bars = bars
125
+ end
126
+
127
+ protected
128
+ def _show()
129
+ Rust["plotter.bars"] = @bars.values
130
+ Rust["plotter.labels"] = @bars.keys
131
+
132
+ Rust._eval("names(plotter.bars) <- plotter.labels")
133
+
134
+ function = Rust::Function.new("barplot")
135
+ function.options = self._augmented_options
136
+ function.arguments << Rust::Variable.new("plotter.bars")
137
+
138
+ function.call
139
+
140
+ return self
141
+ end
142
+ end
143
+ end
@@ -1,37 +1,75 @@
1
- require_relative 'rust-core'
2
- require_relative 'rust-calls'
1
+ require_relative '../core'
2
+
3
+ ##
4
+ # Module that contains classes for plotting.
3
5
 
4
6
  module Rust::Plots
7
+
8
+ ##
9
+ # Represents a generic plot in R.
10
+
5
11
  class BasePlot
12
+
13
+ ##
14
+ # Creates a new base plot object.
15
+
6
16
  def initialize
7
17
  @renderables = []
8
18
  @options = Rust::Options.new
9
19
  @override_options = true
10
20
  end
11
21
 
22
+ ##
23
+ # Sets the x-axis label.
24
+
12
25
  def x_label(label)
13
26
  @options['xlab'] = label
14
27
 
15
28
  return self
16
29
  end
17
30
 
31
+ ##
32
+ # Sets the y-axis label.
33
+
18
34
  def y_label(label)
19
35
  @options['ylab'] = label
20
36
 
21
37
  return self
22
38
  end
23
39
 
40
+ ##
41
+ # Returns a color palette of the given +size+.
42
+
43
+ def palette(size)
44
+ if size <= 1
45
+ return ['black']
46
+ else
47
+ return Rust._pull("hcl.colors(n=#{size})")
48
+ end
49
+ end
50
+
51
+ ##
52
+ # Sets the limits for the x-axis.
53
+
24
54
  def x_range(range)
25
55
  @options['xlim'] = range
26
56
 
27
57
  return self
28
58
  end
59
+ alias :xlim :x_range
60
+
61
+ ##
62
+ # Sets the limits for the y-axis.
29
63
 
30
64
  def y_range(range)
31
65
  @options['ylim'] = range
32
66
 
33
67
  return self
34
68
  end
69
+ alias :ylim :y_range
70
+
71
+ ##
72
+ # Adds an +axis+ to show instead of the default ones.
35
73
 
36
74
  def axis(axis)
37
75
  @options['xaxt'] = 'n'
@@ -42,18 +80,27 @@ module Rust::Plots
42
80
  return self
43
81
  end
44
82
 
83
+ ##
84
+ # Shows the given +grid+.
85
+
45
86
  def grid(grid)
46
87
  self._add_renderable(grid)
47
88
 
48
89
  return self
49
90
  end
50
91
 
92
+ ##
93
+ # Sets the +title+ of the plot.
94
+
51
95
  def title(title)
52
96
  @options['main'] = title
53
97
 
54
98
  return self
55
99
  end
56
100
 
101
+ ##
102
+ # Sets the +color+ of the plot.
103
+
57
104
  def color(color)
58
105
  @options['col'] = color
59
106
 
@@ -67,6 +114,9 @@ module Rust::Plots
67
114
  return self
68
115
  end
69
116
 
117
+ ##
118
+ # Sets any R +option+ with the given +value+.
119
+
70
120
  def []=(option, value)
71
121
  @options[option.to_s] = value
72
122
  end
@@ -75,6 +125,9 @@ module Rust::Plots
75
125
  @override_options = false
76
126
  end
77
127
 
128
+ ##
129
+ # Shows the plot in a window.
130
+
78
131
  def show()
79
132
  Rust.exclusive do
80
133
  self._show
@@ -84,6 +137,9 @@ module Rust::Plots
84
137
  return self
85
138
  end
86
139
 
140
+ ##
141
+ # Prints the plot on a PDF file at path. +options+ can be specified for the PDF (e.g., width and height).
142
+
87
143
  def pdf(path, **options)
88
144
  pdf_function = Rust::Function.new("pdf")
89
145
  pdf_function.options = Rust::Options.from_hash(options)
@@ -126,117 +182,21 @@ module Rust::Plots
126
182
  end
127
183
  end
128
184
 
129
- class ScatterPlot < BasePlot
130
- def initialize(x, y)
131
- super()
132
- @x = x
133
- @y = y
134
- end
135
-
136
- def thickness(t)
137
- self['lwd'] = t
138
-
139
- return self
140
- end
141
-
142
- def lines()
143
- self['type'] = "l"
144
-
145
- return self
146
- end
147
-
148
- def points()
149
- self['type'] = "p"
150
-
151
- return self
152
- end
153
-
154
- def lines_and_points()
155
- self['type'] = "b"
156
-
157
- return self
158
- end
159
-
160
- protected
161
- def _show()
162
- Rust["plotter.x"] = @x
163
- Rust["plotter.y"] = @y
164
-
165
- function = Rust::Function.new("plot")
166
- function.options = self._augmented_options
167
- function.arguments << Rust::Variable.new("plotter.x")
168
- function.arguments << Rust::Variable.new("plotter.y")
169
-
170
- function.call
171
-
172
- return self
173
- end
174
- end
175
-
176
- class DistributionPlot < BasePlot
177
- def initialize
178
- super()
179
- @series = []
180
- end
181
-
182
- def series(data, **options)
183
- @series << [data, options]
184
-
185
- return self
186
- end
187
- end
188
-
189
- class DensityPlot < DistributionPlot
190
- protected
191
- def _show()
192
- first = true
193
- @series.each do |data, options|
194
- Rust["plotter.series"] = data
195
-
196
- if first
197
- first = false
198
- command = "plot"
199
- else
200
- command = "lines"
201
- end
202
-
203
- function = Rust::Function.new(command)
204
- function.options = self._augmented_options({"col" => options[:color]})
205
- function.arguments << Rust::Variable.new("density(plotter.series)")
206
- function.call
207
- end
208
-
209
- return self
210
- end
211
- end
212
-
213
- class BoxPlot < DistributionPlot
214
- protected
215
- def _show()
216
- function = Rust::Function.new("boxplot")
217
-
218
- names = []
219
- @series.each_with_index do |data, i|
220
- series, options = *data
221
- varname = "plotter.series#{i}"
222
- Rust[varname] = series
223
- function.arguments << Rust::Variable.new(varname)
224
- names << (options[:name] || (i+1).to_s)
225
- end
226
-
227
- function.options = self._augmented_options({'names' => names})
228
-
229
- function.call
230
-
231
- return self
232
- end
233
- end
185
+ ##
186
+ # Represents any element that can be rendered in a plot (e.g., axes or grids).
234
187
 
235
188
  class Renderable
189
+
190
+ ##
191
+ # Creates a new empty renderable object.
192
+
236
193
  def initialize
237
194
  @options = Rust::Options.new
238
195
  end
239
196
 
197
+ ##
198
+ # Sets an option for the renderable object.
199
+
240
200
  def []=(option, value)
241
201
  @options[option] = value
242
202
 
@@ -249,12 +209,18 @@ module Rust::Plots
249
209
  end
250
210
  end
251
211
 
212
+ ##
213
+ # Represents an axis for a plot.
214
+
252
215
  class Axis < Renderable
253
216
  BELOW = 1
254
217
  LEFT = 2
255
218
  ABOVE = 3
256
219
  RIGHT = 4
257
220
 
221
+ ##
222
+ # Creates a new axis at the given +side+ (constants BELOW, LEFT, ABOVE, and RIGHT are available).
223
+
258
224
  def initialize(side)
259
225
  super()
260
226
 
@@ -297,7 +263,14 @@ module Rust::Plots
297
263
  end
298
264
  end
299
265
 
266
+ ##
267
+ # Represents a grid for a plot.
268
+
300
269
  class Grid < Renderable
270
+
271
+ ##
272
+ # Creates a new grid
273
+
301
274
  def initialize
302
275
  super()
303
276
 
@@ -305,36 +278,54 @@ module Rust::Plots
305
278
  @y = Float::NAN
306
279
  end
307
280
 
281
+ ##
282
+ # Sets the x intervals.
283
+
308
284
  def x(value)
309
285
  @x = value
310
286
 
311
287
  return self
312
288
  end
313
289
 
290
+ ##
291
+ # Sets the y intervals.
292
+
314
293
  def y(value)
315
294
  @y = value
316
295
 
317
296
  return self
318
297
  end
319
298
 
299
+ ##
300
+ # Automatically sets the x intervals.
301
+
320
302
  def auto_x
321
303
  @x = nil
322
304
 
323
305
  return self
324
306
  end
325
307
 
308
+ ##
309
+ # Automatically sets the y intervals.
310
+
326
311
  def auto_y
327
312
  @y = nil
328
313
 
329
314
  return self
330
315
  end
331
316
 
317
+ ##
318
+ # Hides x axis lines.
319
+
332
320
  def hide_x
333
321
  @x = Float::NAN
334
322
 
335
323
  return self
336
324
  end
337
325
 
326
+ ##
327
+ # Hides y axis lines.
328
+
338
329
  def hide_y
339
330
  @y = Float::NAN
340
331
 
@@ -0,0 +1,75 @@
1
+ require_relative 'core'
2
+
3
+ module Rust::Plots
4
+
5
+ ##
6
+ # Represents any distribution-related plot (e.g., boxplots).
7
+
8
+ class DistributionPlot < BasePlot
9
+ def initialize
10
+ super()
11
+ @series = []
12
+ end
13
+
14
+ ##
15
+ # Adds a series of data points. +options+ can be specified and directly passed to the R plotting function.
16
+
17
+ def series(data, **options)
18
+ @series << [data, options]
19
+
20
+ return self
21
+ end
22
+ end
23
+
24
+ ##
25
+ # Represents a density plot in R.
26
+
27
+ class DensityPlot < DistributionPlot
28
+ protected
29
+ def _show()
30
+ first = true
31
+ @series.each do |data, options|
32
+ Rust["plotter.series"] = data
33
+
34
+ if first
35
+ first = false
36
+ command = "plot"
37
+ else
38
+ command = "lines"
39
+ end
40
+
41
+ function = Rust::Function.new(command)
42
+ function.options = self._augmented_options({"col" => options[:color]})
43
+ function.arguments << Rust::Variable.new("density(plotter.series)")
44
+ function.call
45
+ end
46
+
47
+ return self
48
+ end
49
+ end
50
+
51
+ ##
52
+ # Represents a boxplot in R.
53
+
54
+ class BoxPlot < DistributionPlot
55
+ protected
56
+ def _show()
57
+ function = Rust::Function.new("boxplot")
58
+
59
+ names = []
60
+ @series.each_with_index do |data, i|
61
+ series, options = *data
62
+ varname = "plotter.series#{i}"
63
+ Rust[varname] = series
64
+ function.arguments << Rust::Variable.new(varname)
65
+ names << (options[:name] || (i+1).to_s)
66
+ end
67
+
68
+ function.options = self._augmented_options({'names' => names})
69
+
70
+ function.call
71
+
72
+ return self
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,4 @@
1
+ self_path = File.expand_path(__FILE__)
2
+ Dir.glob(File.dirname(self_path) + "/*.rb").each do |lib|
3
+ require_relative lib unless lib == self_path
4
+ end
@@ -1,7 +1,18 @@
1
- require_relative 'rust-core'
1
+ require_relative '../core'
2
2
 
3
- module Rust:: Correlation
3
+ ##
4
+ # Module containing all the correlation-related statistics.
5
+
6
+ module Rust::Correlation
7
+
8
+ ##
9
+ # Pearson correlation utility methods.
10
+
4
11
  class Pearson
12
+
13
+ ##
14
+ # Runs the Pearson correlation test between +d1+ and +d2+.
15
+
5
16
  def self.test(d1, d2)
6
17
  raise TypeError, "Expecting Array of numerics" if !d1.is_a?(Array) || !d1.all? { |e| e.is_a?(Numeric) }
7
18
  raise TypeError, "Expecting Array of numerics" if !d2.is_a?(Array) || !d2.all? { |e| e.is_a?(Numeric) }
@@ -23,12 +34,22 @@ module Rust:: Correlation
23
34
  end
24
35
  end
25
36
 
37
+ ##
38
+ # Returns the Pearson correlation index between +d1+ and +d2+
39
+
26
40
  def self.estimate(d1, d2)
27
41
  self.test(d1, d2).correlation
28
42
  end
29
43
  end
30
44
 
45
+ ##
46
+ # Spearman correlation utility methods.
47
+
31
48
  class Spearman
49
+
50
+ ##
51
+ # Runs the Spearman correlation test between +d1+ and +d2+.
52
+
32
53
  def self.test(d1, d2)
33
54
  raise TypeError, "Expecting Array of numerics" if !d1.is_a?(Array) || !d1.all? { |e| e.is_a?(Numeric) }
34
55
  raise TypeError, "Expecting Array of numerics" if !d2.is_a?(Array) || !d2.all? { |e| e.is_a?(Numeric) }
@@ -50,12 +71,22 @@ module Rust:: Correlation
50
71
  end
51
72
  end
52
73
 
74
+ ##
75
+ # Returns the Spearman correlation index between +d1+ and +d2+
76
+
53
77
  def self.estimate(d1, d2)
54
78
  self.test(d1, d2).correlation
55
79
  end
56
80
  end
57
81
 
82
+ ##
83
+ # Kendall correlation utility methods.
84
+
58
85
  class Kendall
86
+
87
+ ##
88
+ # Runs the Kendall correlation test between +d1+ and +d2+.
89
+
59
90
  def self.test(d1, d2)
60
91
  raise TypeError, "Expecting Array of numerics" if !d1.is_a?(Array) || !d1.all? { |e| e.is_a?(Numeric) }
61
92
  raise TypeError, "Expecting Array of numerics" if !d2.is_a?(Array) || !d2.all? { |e| e.is_a?(Numeric) }
@@ -64,7 +95,7 @@ module Rust:: Correlation
64
95
  Rust['correlation.a'] = d1
65
96
  Rust['correlation.b'] = d2
66
97
 
67
- _, warnings = Rust._eval("correlation.result <- cor.test(correlation.a, correlation.b, method='p')", true)
98
+ _, warnings = Rust._eval("correlation.result <- cor.test(correlation.a, correlation.b, method='k')", true)
68
99
 
69
100
  result = Result.new
70
101
  result.name = "Kendall's rank correlation tau"
@@ -77,11 +108,17 @@ module Rust:: Correlation
77
108
  end
78
109
  end
79
110
 
111
+ ##
112
+ # Returns the Kendall correlation index between +d1+ and +d2+
113
+
80
114
  def self.estimate(d1, d2)
81
115
  self.test(d1, d2).correlation
82
116
  end
83
117
  end
84
118
 
119
+ ##
120
+ # Result of a correlation test.
121
+
85
122
  class Result
86
123
  attr_accessor :name
87
124
  attr_accessor :statistics
@@ -96,10 +133,16 @@ module Rust:: Correlation
96
133
  @exact = true
97
134
  end
98
135
 
136
+ ##
137
+ # Returns the statistic with the specified +name+.
138
+
99
139
  def [](name)
100
140
  return @statistics[name.to_sym]
101
141
  end
102
142
 
143
+ ##
144
+ # Sets the +value+ for the the statistic with the specified +name+.
145
+
103
146
  def []=(name, value)
104
147
  @statistics[name.to_sym] = value
105
148
  end