Class: Silicium::Plotter::Image

Inherits:
Object
  • Object
show all
Includes:
Geometry
Defined in:
lib/plotter.rb

Overview

A class representing canvas for plotting bar charts and function graphs

Instance Method Summary collapse

Methods included from Geometry

#brute_min, #clockwise, #counter_clockwise, #cut_by_eq, #distance_point_line2d, #distance_point_line_normalized2d, #distance_point_to_point2d, #divide_min, #insert_eq, #minimal_convex_hull_2d, #needed_variables_order?, #not_polygon?, #oriented_area, #process_cf, #process_free_member, #process_line_by_coordinates, #put_point_in_part, #sign, #vector_length, #vectors_product

Constructor Details

#initialize(width, height, bg_color = Color::TRANSPARENT, padding = 5) ⇒ Image

Creates a new plot with chosen width and height parameters with background colored bg_color



73
74
75
76
# File 'lib/plotter.rb', line 73

def initialize(width, height, bg_color = Color::TRANSPARENT, padding = 5)
  @image = ChunkyPNG::Image.new(width, height, bg_color)
  @padding = padding
end

Instance Method Details

#bar_chart(bars, bar_width, bars_color = Color('red @ 1.0'), axis_color = Color::BLACK) ⇒ Object

Draws a bar chart in the plot using provided bars, each of them has width of bar_width and colored bars_color



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/plotter.rb', line 107

def bar_chart(bars, bar_width,
              bars_color = Color('red @ 1.0'),
              axis_color = Color::BLACK)
  if bars.count * bar_width > @image.width
    raise ArgumentError,
          'Not enough big size of image to plot these number of bars'
  end

  # Values of x and y on borders of plot
  min = Point.new([bars.collect { |k, _| k }.min, 0].min,
                  [bars.collect { |_, v| v }.min, 0].min)
  max = Point.new([bars.collect { |k, _| k }.max, 0].max,
                  [bars.collect { |_, v| v }.max, 0].max)

  # Dots per unit
  dpu = Point.new(
    (@image.width - 2 * @padding).to_f / (max.x - min.x + bar_width),
    (@image.height - 2 * @padding).to_f / (max.y - min.y)
  )

  draw_axis(min, dpu, axis_color)

  bars.each do |x, y| # Cycle drawing bars
    l_up_x = @padding + ((x + min.x.abs) * dpu.x).floor
    l_up_y = if y.negative?
               @image.height - @padding - (min.y.abs * dpu.y).ceil + 1
             else
               @image.height - @padding - ((y + min.y.abs) * dpu.y).ceil
             end
    rectangle(Point.new(l_up_x, l_up_y),
              bar_width, (y.abs * dpu.y).ceil,
              bars_color)
  end
end

#export(filename) ⇒ Object

Exports plotted image to file filename



144
145
146
# File 'lib/plotter.rb', line 144

def export(filename)
  @image.save(filename, interlace: true)
end

#rectangle(left_upper, width, height, color) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/plotter.rb', line 78

def rectangle(left_upper, width, height, color)
  x_end = left_upper.x + width - 1
  y_end = left_upper.y + height - 1
  (left_upper.x..x_end).each do |i|
    (left_upper.y..y_end).each { |j| @image[i, j] = color }
  end
end