Skip to content

Commit e6ebd88

Browse files
authored
Merge branch 'integration' into branch_two
2 parents 508ea9e + 56247f7 commit e6ebd88

16 files changed

Lines changed: 233 additions & 85 deletions

File tree

lib/rubyplot/artist/axes.rb

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,15 @@ class Axes < Base
2020
attr_accessor :x_range
2121
# Range of Y axis.
2222
attr_accessor :y_range,
23-
:x_tick_count, :y_tick_count, :text_font, :grid,
24-
:bounding_box, :x_axis_padding, :y_axis_padding, :origin,
23+
:text_font, :grid,
24+
:bounding_box, :origin,
2525
:title_shift, :title_margin
26-
27-
# A hash of names for the individual columns, where the key is the array
28-
# index for the column this label represents.
29-
#
30-
# Not all columns need to be named.
31-
#
32-
# Example: 0 => 2005, 3 => 2006, 5 => 2007, 7 => 2008
33-
attr_accessor :x_ticks
34-
attr_accessor :y_ticks
3526
# Main title for this Axes.
3627
attr_accessor :title
3728
# Rubyplot::Figure object to which this Axes belongs.
3829
attr_reader :figure
3930
# Array of plots contained in this Axes.
4031
attr_reader :plots
41-
# data variables for something
42-
attr_reader :raw_rows
4332

4433
attr_reader :geometry, :font, :marker_font_size, :legend_font_size,
4534
:title_font_size, :scale, :font_color, :marker_color, :axes,
@@ -71,8 +60,6 @@ def initialize figure
7160
@y_axis_margin = 40.0
7261
@x_range = [nil, nil]
7362
@y_range = [nil, nil]
74-
@x_tick_count = :default
75-
@y_tick_count = :default
7663

7764
@origin = [nil, nil]
7865
@title = ""
@@ -81,7 +68,6 @@ def initialize figure
8168
@text_font = :default
8269
@grid = true
8370
@bounding_box = true
84-
@x_ticks = {}
8571
@plots = []
8672

8773
@raw_rows = width * (height/width)
@@ -124,6 +110,9 @@ def legend_box_iy
124110

125111
# Write an image to a file by communicating with the backend.
126112
def draw
113+
assign_plot_defaults
114+
consolidate_plots
115+
gather_plot_data
127116
configure_title
128117
calculate_xy_axes_origin
129118
configure_xy_axes
@@ -191,8 +180,25 @@ def height
191180
(1 - (@figure.top_spacing + @figure.bottom_spacing)) * @figure.height
192181
end
193182

183+
def x_ticks= ticks_hash
184+
@x_ticks = ticks_hash
185+
end
186+
194187
private
195188

189+
def assign_plot_defaults
190+
assign_label_colors
191+
end
192+
193+
def assign_label_colors
194+
@plots.each_with_index do |p, i|
195+
if p.color == :default
196+
p.color = @figure.theme_options[:label_colors][
197+
i % @figure.theme_options[:label_colors].size]
198+
end
199+
end
200+
end
201+
196202
def add_plot plot_type, *args, &block
197203
plot = with_backend plot_type, *args
198204
yield(plot) if block_given?
@@ -211,11 +217,6 @@ def with_backend plot_type, *args
211217
plot
212218
end
213219

214-
def prepare_legend
215-
@legends = @plots.map(&:create_legend)
216-
@legends.each { |l| l.draw }
217-
end
218-
219220
# Figure out the co-ordinates of the title text w.r.t Axes.
220221
def configure_title
221222
@title = Rubyplot::Artist::Text.new(
@@ -300,6 +301,33 @@ def label_string(value, increment)
300301
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{THOUSAND_SEPARATOR}")
301302
parts.join('.')
302303
end
304+
305+
def consolidate_plots
306+
bars = @plots.grep(Rubyplot::Artist::Plot::Bar)
307+
if !bars.empty?
308+
@plots.delete_if { |p| p.is_a?(Rubyplot::Artist::Plot::Bar) }
309+
@plots << Rubyplot::Artist::Plot::MultiBars.new(self, bar_plots: bars)
310+
end
311+
end
312+
313+
def gather_plot_data
314+
set_xrange
315+
set_yrange
316+
end
317+
318+
def set_xrange
319+
if @x_range[0].nil? && @x_range[1].nil?
320+
@x_range[0] = @plots.map { |p| p.x_min }.min
321+
@x_range[1] = @plots.map { |p| p.x_max }.max
322+
end
323+
end
324+
325+
def set_yrange
326+
if @y_range[0].nil? && @y_range[1].nil?
327+
@y_range[0] = @plots.map { |p| p.y_min }.min
328+
@y_range[1] = @plots.map { |p| p.y_max }.max
329+
end
330+
end
303331
end # class Axes
304332
end # moudle Artist
305333
end # module Rubyplot

lib/rubyplot/artist/axis/base.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ class Base
66
FINISH_ARROW_LENGTH = 10.0
77

88
attr_reader :label, :ticks, :major_ticks_count, :min_val, :max_val, :title
9-
attr_reader :abs_x1, :abs_x2, :abs_y1, :abs_y2, :backend
10-
attr_reader :stroke_width
9+
attr_reader :abs_x1, :abs_x2, :abs_y1, :abs_y2, :backend, :length
10+
attr_reader :stroke_width, :major_ticks
1111

1212
def initialize axes, title, min_val, max_val
1313
@axes = axes
@@ -16,6 +16,7 @@ def initialize axes, title, min_val, max_val
1616
@max_val = max_val
1717
@stroke_width = 1.0
1818
@backend = @axes.backend
19+
@major_ticks = []
1920
end
2021
end # class Base
2122
end # class Axis

lib/rubyplot/artist/axis/x_axis.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,31 @@ def initialize(*)
1111
@abs_y2 = @axes.origin[1]
1212
@major_ticks_count = 5
1313
@major_ticks_distance = (@abs_x2 - @abs_x1) / @major_ticks_count
14-
@x_ticks = []
14+
@length = (@abs_x2 - @abs_x1).abs
1515
configure_axis_line
1616
populate_major_x_ticks
1717
configure_title
1818
end
1919

2020
def draw
2121
@line.draw
22-
@x_ticks.each(&:draw)
22+
@major_ticks.each(&:draw)
2323
@title.draw
2424
end
2525

2626
private
2727

2828
def configure_axis_line
2929
@line = Rubyplot::Artist::Line2D.new(
30-
self, abs_x1: @abs_x1, abs_y1: @abs_y1, abs_x2: @abs_x2, abs_y2: @abs_y2)
31-
#stroke_width: @stroke_width)
30+
self, abs_x1: @abs_x1, abs_y1: @abs_y1, abs_x2: @abs_x2, abs_y2: @abs_y2,
31+
stroke_width: @stroke_width)
3232
end
3333

3434
def populate_major_x_ticks
3535
value_distance = (@max_val) / @major_ticks_count.to_f
3636
@major_ticks_count.times do |count|
3737
count += 1
38-
@x_ticks << Rubyplot::Artist::XTick.new(
38+
@major_ticks << Rubyplot::Artist::XTick.new(
3939
@axes,
4040
abs_x: count * @major_ticks_distance + @abs_x1,
4141
abs_y: @abs_y1,

lib/rubyplot/artist/axis/y_axis.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ def initialize(*)
88
@abs_x2 = @axes.origin[0]
99
@abs_y2 = @axes.origin[1] - (@axes.height - @axes.x_axis_margin)
1010
@y_ticks = []
11+
@length = (@abs_y1 - @abs_y2).abs
1112
configure_axis_line
1213
configure_title
1314
populate_major_y_ticks

lib/rubyplot/artist/figure.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,17 @@ class Figure < Artist::Base
2828
attr_reader :theme_options
2929
attr_reader :marker_color
3030
attr_reader :font_color
31-
def initialize
31+
32+
# Initialize a Rubyplot::Artist::Figure object.
33+
# @param height [Integer] nil Height in pixels of the complete Figure.
34+
# @param width [Integer] nil Width in pixels of the complete Figure.
35+
def initialize(height: nil, width: nil)
3236
@title = ''
3337
@nrows = 1
3438
@ncols = 1
3539
@backend = Rubyplot::Backend::MagickWrapper.new
36-
@width = DEFAULT_TARGET_WIDTH
37-
@height = @width * 0.75
40+
@width = width || DEFAULT_TARGET_WIDTH
41+
@height = height || @width * 0.75
3842
@abs_x = 0
3943
@abs_y = 0
4044
@top_spacing = 0.05
@@ -58,6 +62,8 @@ def write file_name
5862
@backend.write(file_name)
5963
end
6064

65+
private
66+
6167
def setup_default_theme
6268
defaults = {
6369
marker_color: 'white',

lib/rubyplot/artist/legend_box.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class LegendBox < Base
1515
def initialize(axes, abs_x:, abs_y:)
1616
super(axes.backend, abs_x, abs_y)
1717
@axes = axes
18-
@border_color = "#000000"
18+
@border_color = :black
1919
@legends = []
2020
configure_dimensions
2121
configure_legends

lib/rubyplot/artist/plot.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
require_relative 'plot/scatter'
33
require_relative 'plot/line'
44
require_relative 'plot/bar'
5+
require_relative 'plot/multi_bars'

lib/rubyplot/artist/plot/bar.rb

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,64 @@ module Plot
44
class Bar < Artist::Plot::Base
55
# Space between the columns.
66
attr_accessor :bar_spacing
7+
# Width of each bar in pixels.
8+
attr_accessor :bar_width
79
# Number between 0 and 1.0 denoting spacing between the bars.
810
# 0.0 means no spacing at all 1.0 means that each bars' width
911
# is nearly 0 (so each bar is a simple line with no X dimension).
10-
attr_reader :spacing_factor
12+
# Denotes the total left + right side space.
13+
attr_reader :spacing_ratio
14+
# X co-ordinates of the lower left corner of the bar.
15+
attr_accessor :abs_x_left
16+
# Y co-ordinates of the lower left corner of the bar.
17+
attr_accessor :abs_y_left
18+
1119
def initialize(*)
1220
super
13-
@spacing_factor = 0.9
21+
@spacing_ratio = 0.1
22+
@abs_x_left = []
23+
@abs_y_left = []
24+
@rectangles = []
1425
end
1526

1627
# Set the spacing factor for this bar plot.
17-
def spacing_factor= sf
18-
raise ValueError, '@spacing_factor must be between 0.00 and 1.00' unless
28+
def spacing_ratio= sf
29+
raise ValueError, '@spacing_ratio must be between 0.00 and 1.00' unless
1930
(sf >= 0) && (sf <= 1)
20-
@spacing_factor = sf
31+
@spacing_ratio = sf
2132
end
22-
33+
34+
# Set Bar plot data.
35+
def data y_values
36+
super(Array.new(y_values.size) { |i| i}, y_values)
37+
end
38+
39+
# Number of bars in this Bar plot
40+
def num_bars
41+
@data[:y_values].size
42+
end
43+
2344
def draw
24-
super
2545
return unless @axes.geometry.has_data
46+
setup_bar_rectangles
47+
@rectangles.each(&:draw)
48+
end
49+
50+
private
51+
52+
def setup_bar_rectangles
53+
@normalized_data[:y_values].each_with_index do |iy, i|
54+
height = iy * @axes.y_axis.length
55+
@rectangles << Rubyplot::Artist::Rectangle.new(
56+
self,
57+
abs_x: @abs_x_left[i],
58+
abs_y: @abs_y_left[i] - height,
59+
width: @bar_width,
60+
height: height,
61+
border_color: @data[:color],
62+
fill_color: @data[:color]
63+
)
64+
end
2665
end
2766
end # class Bar
2867
end # module Plot

lib/rubyplot/artist/plot/base.rb

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ module Rubyplot
22
module Artist
33
module Plot
44
class Base < Artist::Base
5-
attr_reader :axes, :data
5+
attr_reader :axes, :data, :x_max, :x_min, :y_min,
6+
:y_max
67
attr_writer :stroke_width, :stroke_opacity
78

89
def initialize axes
10+
super(axes.backend, axes.abs_x, axes.abs_y)
911
@axes = axes
1012
@backend = @axes.backend
1113
@data = {
12-
label: :default,
14+
label: "",
1315
color: :default
1416
}
1517
@normalized_data = {
@@ -33,38 +35,34 @@ def label= label
3335
end
3436

3537
def color= color
36-
@data[:color] = Rubyplot::Color::COLOR_INDEX[color]
38+
@data[:color] = color
3739
end
3840

3941
def data x_values, y_values
4042
@data[:x_values] = x_values
4143
@data[:y_values] = y_values
4244
# Set column count if this is larger than previous column counts
4345
@axes.geometry.column_count = y_values.length > @axes.geometry.column_count ?
44-
y_values.length : @axes.geometry.column_count
45-
if @axes.y_range[0].nil? && @axes.y_range[1].nil?
46-
@axes.y_range[0] = y_values.min
47-
@axes.y_range[1] = y_values.max
48-
end
49-
if @axes.x_range[1].nil? && @axes.x_range[0].nil?
50-
@axes.x_range[0] = x_values.min
51-
@axes.x_range[1] = x_values.max
52-
end
46+
y_values.length : @axes.geometry.column_count
47+
@y_min = @data[:y_values].min
48+
@y_max = @data[:y_values].max
49+
@x_min = @data[:x_values].min
50+
@x_max = @data[:x_values].max
51+
5352
@axes.geometry.has_data = true
5453
end
5554

56-
# Normalize original data to values between 0-100.
55+
# Normalize original data to values between 0-1. Used for obtaining relative
56+
# values of the data.
5757
def normalize
58-
x_min = @axes.x_range[0] < 0 ? @axes.x_range[0] : 0
59-
y_min = @axes.y_range[0] < 0 ? @axes.y_range[0] : 0
60-
x_spread = @axes.x_range[1] - x_min
61-
y_spread = @axes.y_range[1] - y_min
58+
x_spread = @axes.x_range[1] - @axes.x_range[0]
59+
y_spread = @axes.y_range[1] - @axes.y_range[0]
6260
@normalized_data[:x_values] = @data[:x_values].map do |x|
63-
(x.to_f - x_min) / x_spread
64-
end
61+
(x.to_f - @axes.x_range[0]) / x_spread
62+
end if @data[:x_values]
6563
@normalized_data[:y_values] = @data[:y_values].map do |y|
66-
(y.to_f - y_min) / y_spread
67-
end
64+
(y.to_f - @axes.y_range[0]) / y_spread
65+
end if @data[:y_values]
6866
end
6967
end # class Base
7068
end # module Plot

0 commit comments

Comments
 (0)