rust 0.9 → 0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,122 @@
1
+ require_relative 'core'
2
+
3
+ GGPLOT_EXAMPLES = {}
4
+
5
+ GGPLOT_EXAMPLES[["Quick introduction", /intro/]] = <<-EOS
6
+ bind_ggplot! # Avoid using long module names to reach Rust::Plots::GGPlot (simply includes this module)
7
+
8
+ # Best with a dataframe, but not necessary. If you have it...
9
+ df = Rust.toothgrowth
10
+ plot = PlotBuilder.for_dataframe(df). # Use a dataframe (symbols will be variable names)
11
+ labeled("Example plot"). # "labeled" sets the label to the last set aesthetic item (x, y, or title, in this case)
12
+ with_x(:len).labeled("X data from df"). # Set all the aesthetics (x, y, ...)
13
+ with_y(:dose).labeled("Y data from df").
14
+ draw_points. # Set the geometries to plot (based on the plot type)
15
+ build # Returns the plot ready to use
16
+ plot.show # Show the plot in a window
17
+ plot.save("output.pdf", width: 5, height: 4) # Save the plot, width, height etc. are optional
18
+
19
+ # If you don't have a dataframe...
20
+ plot2 = PlotBuilder.new.
21
+ with_x([1,2,3]).labeled("X data from df").
22
+ with_y([3,4,5]).labeled("Y data from df").
23
+ draw_points.
24
+ build
25
+ plot2.show
26
+ EOS
27
+
28
+ GGPLOT_EXAMPLES[["Scatter plots", /scatter/]] = <<-EOS
29
+ bind_ggplot!
30
+ df = Rust.toothgrowth
31
+ plot = PlotBuilder.for_dataframe(df).
32
+ with_x(:len).labeled("X data").
33
+ with_y(:dose).labeled("Y data").
34
+ draw_points. # To draw points
35
+ draw_lines. # To draw lines (keep both to draw both)
36
+ build
37
+ plot.show
38
+ EOS
39
+
40
+ GGPLOT_EXAMPLES[["Bar plots", /bar/]] = <<-EOS
41
+ bind_ggplot!
42
+ df = Rust.toothgrowth
43
+ plot = PlotBuilder.for_dataframe(df).
44
+ with_x(:len).labeled("X data").
45
+ with_fill(:supp).labeled("Legend"). # Use with_fill or with_color for stacked plots
46
+ draw_bars. # To draw bars
47
+ build
48
+ plot.show
49
+ EOS
50
+
51
+ GGPLOT_EXAMPLES[["Box plots", /box/]] = <<-EOS
52
+ bind_ggplot!
53
+ df = Rust.toothgrowth
54
+ plot = PlotBuilder.for_dataframe(df).
55
+ with_y(:len).labeled("Data to boxplot").
56
+ with_group(:supp).labeled("Groups"). # Groups to plot
57
+ draw_boxplot.
58
+ build
59
+ plot.show
60
+ EOS
61
+
62
+ GGPLOT_EXAMPLES[["Histograms", /hist/]] = <<-EOS
63
+ bind_ggplot!
64
+ df = Rust.toothgrowth
65
+ plot = PlotBuilder.for_dataframe(df).
66
+ with_x(:len).labeled("Data to plot").
67
+ with_fill(:supp).labeled("Color"). # Use with_fill or with_color for multiple plots
68
+ draw_histogram.
69
+ build
70
+ plot.show
71
+ EOS
72
+
73
+ GGPLOT_EXAMPLES[["Themes", /them/]] = <<-EOS
74
+ bind_ggplot!
75
+ df = Rust.toothgrowth
76
+ # The method with_theme allows to change theme options. The method can be called
77
+ # several times, each time the argument does not overwrite the previous options,
78
+ # unless they are specified again (in that case, the last specified ones win).
79
+ plot = PlotBuilder.for_dataframe(df).
80
+ with_x(:len).labeled("X data").
81
+ with_y(:dose).labeled("Y data").
82
+ draw_points.
83
+ with_theme(
84
+ ThemeBuilder.new('bw').
85
+ title(face: 'bold', size: 12). # Each method sets the property for the related element
86
+ legend do |legend| # Legend and other parts can be set like this
87
+ legend.position(:left) # Puts the legend on the left
88
+ end.
89
+ axis do |axis| # Modifies the axes
90
+ axis.line(Theme::BlankElement.new) # Hides the lines for the axes
91
+ axis.text_x(size: 3) # X axis labels
92
+ end.
93
+ panel do |panel|
94
+ panel.grid_major(colour: 'grey70', size: 0.2) # Sets the major ticks grid
95
+ panel.grid_minor(Theme::BlankElement.new) # Hides the minor ticks grid
96
+ end.
97
+ build
98
+ ).build
99
+ plot.show
100
+ EOS
101
+
102
+ module Rust::Plots::GGPlot
103
+ def self.help!(topic = nil)
104
+ unless topic
105
+ puts "Topics:"
106
+ GGPLOT_EXAMPLES.keys.each do |key, matcher|
107
+ puts "- #{key}"
108
+ end
109
+ puts "Call again specifying the topic of interest."
110
+ else
111
+ GGPLOT_EXAMPLES.each do |key, value|
112
+ if topic.match(key[1])
113
+ puts "*** #{key[0]} ***"
114
+ puts value
115
+ return
116
+ end
117
+ end
118
+
119
+ puts "Topic not found"
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,188 @@
1
+ require_relative 'core'
2
+
3
+ Rust.prerequisite("ggplot2")
4
+
5
+ module Rust::Plots::GGPlot
6
+ class PlotBuilder
7
+ def self.for_dataframe(data_frame)
8
+ return PlotBuilder.new(data_frame)
9
+ end
10
+
11
+ def initialize(data=nil)
12
+ @data = data
13
+
14
+ @aes_options = {}
15
+ @label_options = {}
16
+
17
+ @current_context = :title
18
+
19
+ @layers = []
20
+ end
21
+
22
+ def with_x(variable, label = nil)
23
+ variable = variable.to_sym if variable.is_a?(String)
24
+
25
+ @aes_options[:x] = variable
26
+ @current_context = :x
27
+
28
+ return self
29
+ end
30
+
31
+ def with_y(variable)
32
+ variable = variable.to_sym if variable.is_a?(String)
33
+
34
+ @aes_options[:y] = variable
35
+ @current_context = :y
36
+
37
+ return self
38
+ end
39
+
40
+ def with_group(variable)
41
+ variable = variable.to_sym if variable.is_a?(String)
42
+
43
+ @aes_options[:group] = variable
44
+ @current_context = :group
45
+
46
+ return self
47
+ end
48
+
49
+ def with_color(variable)
50
+ variable = variable.to_sym if variable.is_a?(String)
51
+
52
+ @aes_options[:color] = variable
53
+ @current_context = :color
54
+
55
+ return self
56
+ end
57
+
58
+ def with_fill(variable)
59
+ variable = variable.to_sym if variable.is_a?(String)
60
+
61
+ @aes_options[:fill] = variable
62
+ @current_context = :fill
63
+
64
+ return self
65
+ end
66
+
67
+ def labeled(value)
68
+ raise "No context for assigning a label" unless @current_context
69
+ @label_options[@current_context] = value
70
+ @current_context = nil
71
+
72
+ return self
73
+ end
74
+
75
+ def with_x_label(value)
76
+ @label_options[:x] = value
77
+
78
+ return self
79
+ end
80
+
81
+ def with_y_label(value)
82
+ @label_options[:y] = value
83
+
84
+ return self
85
+ end
86
+
87
+ def with_color_label(value)
88
+ @label_options[:color] = value
89
+
90
+ return self
91
+ end
92
+
93
+ def with_title(value)
94
+ @label_options[:title] = value
95
+
96
+ return self
97
+ end
98
+
99
+ def draw_points(**options)
100
+ @layers << GeomPoint.new(**options)
101
+
102
+ @current_context = nil
103
+
104
+ return self
105
+ end
106
+
107
+ def draw_lines(**options)
108
+ @layers << GeomLine.new(**options)
109
+
110
+ @current_context = nil
111
+
112
+ return self
113
+ end
114
+
115
+ def draw_bars(**options)
116
+ @layers << GeomBar.new(**options)
117
+
118
+ @current_context = nil
119
+
120
+ return self
121
+ end
122
+
123
+ def draw_cols(**options)
124
+ @layers << GeomCol.new(**options)
125
+
126
+ @current_context = nil
127
+
128
+ return self
129
+ end
130
+
131
+ def draw_boxplot(**options)
132
+ @layers << GeomBoxplot.new(**options)
133
+
134
+ @current_context = nil
135
+
136
+ return self
137
+ end
138
+
139
+ def draw_histogram(**options)
140
+ @layers << GeomHistogram.new(**options)
141
+
142
+ @current_context = nil
143
+
144
+ return self
145
+ end
146
+
147
+ def draw_density(**options)
148
+ @layers << GeomDensity.new(**options)
149
+
150
+ @current_context = nil
151
+
152
+ return self
153
+ end
154
+
155
+ def with_theme(theme)
156
+ @layers << theme
157
+
158
+ @current_context = nil
159
+
160
+ return self
161
+ end
162
+
163
+ def flip_coordinates
164
+ @layers << FlipCoordinates.new
165
+
166
+ @current_context = nil
167
+
168
+ return self
169
+ end
170
+
171
+ def build
172
+ plot = Plot.new(@data, Aes.new(**@aes_options))
173
+ plot.theme = @theme if @theme
174
+ plot << @layers if @layers.size > 0
175
+ if @label_options.size > 0
176
+ if @label_options.keys.include?(:group)
177
+ value = @label_options.delete(:group)
178
+ selected = [:x, :y] - @label_options.keys
179
+ @label_options[selected.first] = value if selected.size == 1
180
+ end
181
+
182
+ plot << Labels.new(**@label_options)
183
+ end
184
+
185
+ return plot
186
+ end
187
+ end
188
+ end