Skip to content

Commit 9ec40c7

Browse files
committed
add area plot
1 parent c47d643 commit 9ec40c7

9 files changed

Lines changed: 87 additions & 15 deletions

File tree

lib/rubyplot/artist.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
require_relative 'artist/axes'
1111
require_relative 'artist/rectangle'
1212
require_relative 'artist/circle'
13+
require_relative 'artist/polygon'

lib/rubyplot/artist/axes.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,9 @@ def line! *args, &block
142142
end
143143

144144
def area! *args, &block
145-
add_plot "Area", *args, &block
145+
plot = Rubyplot::Artist::Plot::Area.new self
146+
yield(plot) if block_given?
147+
@plots << plot
146148
end
147149

148150
def bubble! *args, &block
@@ -209,17 +211,17 @@ def assign_default_label_colors
209211

210212
def assign_x_ticks
211213
unless @x_ticks
212-
val_distance = @x_range[1] / @num_x_ticks.to_f
213-
@x_ticks = Array.new(@num_x_ticks) { |c| (c*val_distance).to_s }
214+
val_distance = (@x_range[1] - @x_range[0]).abs / @num_x_ticks.to_f
215+
@x_ticks = (@x_range[0]..@x_range[1]).step(val_distance).map { |i| i }
214216
end
215217
unless @x_ticks.all? { |t| t.is_a?(Rubyplot::Artist::XTick) }
216-
inter_ticks_distance = @x_axis.length / @num_x_ticks
218+
inter_ticks_distance = @x_axis.length / (@num_x_ticks - 1)
217219
@x_ticks.map!.with_index do |tick_label, i|
218220
Rubyplot::Artist::XTick.new(
219221
self,
220222
abs_x: i * inter_ticks_distance + @x_axis.abs_x1,
221223
abs_y: @origin[1],
222-
label: tick_label,
224+
label: Rubyplot::Utils.format_label(tick_label),
223225
length: 6,
224226
label_distance: 10
225227
)

lib/rubyplot/artist/plot.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
require_relative 'plot/bar'
55
require_relative 'plot/multi_bars'
66
require_relative 'plot/bubble'
7+
require_relative 'plot/area'

lib/rubyplot/artist/plot/area.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module Rubyplot
2+
module Artist
3+
module Plot
4+
class Area < Artist::Plot::Base
5+
attr_reader :sorted_data
6+
def initialize(*)
7+
super
8+
@sorted_data = true
9+
end
10+
11+
def data x_values, y_values=[]
12+
y_values = Array.new(x_values.size) { |i| i } if y_values.empty?
13+
x_values.sort! if @sorted_data
14+
super(x_values, y_values)
15+
end
16+
17+
def draw
18+
poly_points = []
19+
@normalized_data[:y_values].each_with_index do |iy, idx_y|
20+
ix = @normalized_data[:x_values][idx_y]
21+
abs_x = ix * @axes.x_axis.length + @axes.abs_x + @axes.y_axis_margin
22+
abs_y = (@axes.y_axis.length - iy * @axes.y_axis.length) + @axes.abs_y
23+
poly_points << [abs_x, abs_y]
24+
end
25+
poly_points << [@axes.x_axis.abs_x2, @axes.origin[1] - @axes.x_axis.stroke_width]
26+
poly_points << [@axes.origin[0], @axes.origin[1] - @axes.x_axis.stroke_width]
27+
Rubyplot::Artist::Polygon.new(
28+
self,
29+
coords: poly_points,
30+
color: @data[:color],
31+
fill_opacity: 0.3
32+
).draw
33+
end
34+
end # class Area
35+
end # module Plot
36+
end # module Artist
37+
end # module Rubyplot

lib/rubyplot/artist/plot/line.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,12 @@ def draw_single_point
3333

3434
def draw_lines
3535
prev_x = prev_y = nil
36-
y_axis_length = (@axes.y_axis.abs_y2 - @axes.y_axis.abs_y1).abs
3736
@normalized_data[:x_values].each_with_index do |ix, idx_ix|
3837
iy = @normalized_data[:y_values][idx_ix]
3938
next if ix.nil? || iy.nil?
4039
new_x = ix * (@axes.x_axis.abs_x2 - @axes.x_axis.abs_x1).abs + @axes.abs_x +
4140
@axes.y_axis_margin
42-
new_y = (y_axis_length - iy * y_axis_length) + @axes.abs_y
41+
new_y = (@axes.y_axis.length - iy * @axes.y_axis.length) + @axes.abs_y
4342

4443
if !(prev_x.nil? && prev_y.nil?)
4544
Rubyplot::Artist::Line2D.new(

lib/rubyplot/artist/polygon.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module Rubyplot
2+
module Artist
3+
class Polygon < Base
4+
def initialize(owner, coords:, fill_opacity: 0.0, color: :default, stroke: 'transparent')
5+
@backend = owner.backend
6+
@coords = coords
7+
@fill_opacity = fill_opacity
8+
@color = color
9+
@stroke = stroke
10+
end
11+
12+
def draw
13+
@backend.draw_polygon(
14+
coords: @coords,
15+
stroke: @stroke,
16+
color: Rubyplot::Color::COLOR_INDEX[@color],
17+
fill_opacity: @fill_opacity
18+
)
19+
end
20+
end # class Polygon
21+
end # module Artist
22+
end # module Rubyplot

lib/rubyplot/backend/magick_wrapper.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@ def draw_circle(x:,y:,radius:,stroke_opacity:,stroke_width:,color:)
115115
@draw.circle(x,y,x-radius,y)
116116
end
117117

118+
# Draw a polygon.
119+
#
120+
# @param coords [Array[Array]] Array of Arrays where first element of each sub-array is
121+
# the X co-ordinate and the second element is the Y co-ordinate.
122+
def draw_polygon(coords: , fill_opacity: 0.0, color: "#000000",
123+
stroke: "transparent")
124+
@draw.stroke stroke
125+
@draw.fill color
126+
@draw.fill_opacity fill_opacity
127+
@draw.polygon *coords.flatten
128+
end
129+
118130
def write file_name
119131
@draw.draw(@base_image)
120132
@base_image.write(file_name)

lib/rubyplot/utils.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ class << self
55
def format_label label
66
if label.is_a? Float
77
format('%0.2f', label)
8+
elsif label.is_a? String
9+
label
810
end
911
end
1012
end

spec/axes_spec.rb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
FileUtils.mkdir_p @temp_dir
172172
end
173173

174-
it "plots a single bubble plot", focus: true do
174+
it "plots a single bubble plot" do
175175
fig = Rubyplot::Figure.new
176176
axes = fig.add_subplot 0,0
177177
axes.bubble! do |p|
@@ -222,13 +222,9 @@
222222
p.label = "Jimmy"
223223
end
224224
axes.title = "Visual simple area graph test."
225-
axes.x_ticks = {
226-
0 => '0',
227-
2 => '2',
228-
4 => '4',
229-
6 => '6'
230-
}
231-
225+
axes.num_x_ticks = 5
226+
axes.x_ticks = ['0', '22', '44', '66', '88',]
227+
232228
file = "/#{Rubyplot.backend}_simple_area.png"
233229
fig.write(@temp_dir + file)
234230

0 commit comments

Comments
 (0)