class Silicium::Plotter::Image

A class representing canvas for plotting bar charts and function graphs

Public Class Methods

new(width, height, bg_color = Color::TRANSPARENT, padding = 5) click to toggle source

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

# 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

Public Instance Methods

bar_chart(bars, bar_width, bars_color = Color('red @ 1.0'), axis_color = Color::BLACK) click to toggle source

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

# 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) click to toggle source

Exports plotted image to file filename

# File lib/plotter.rb, line 144
def export(filename)
  @image.save(filename, interlace: true)
end
rectangle(left_upper, width, height, color) click to toggle source
# 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

Private Instance Methods

draw_axis(min, dpu, axis_color) click to toggle source
# File lib/plotter.rb, line 88
def draw_axis(min, dpu, axis_color)
  # Axis OX
  rectangle(Point.new(
              @padding,
              @image.height - @padding - (min.y.abs * dpu.y).ceil
            ),
            @image.width - 2 * @padding,
            1,
            axis_color)
  # Axis OY
  rectangle(Point.new(@padding + (min.x.abs * dpu.x).ceil, @padding),
            1, @image.height - 2 * @padding, axis_color)
end