class Charty::Plotters::BarPlotter
Attributes
cap_size[R]
error_color[R]
error_width[R]
log[R]
Public Class Methods
new(data: nil, variables: {}, **options, &block)
click to toggle source
Calls superclass method
# File lib/charty/plotters/bar_plotter.rb, line 7 def initialize(data: nil, variables: {}, **options, &block) x, y, color = variables.values_at(:x, :y, :color) super(x, y, color, data: data, **options, &block) end
Public Instance Methods
cap_size=(cap_size)
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 41 def cap_size=(cap_size) @cap_size = check_number(cap_size, :cap_size, allow_nil: true) end
error_color=(error_color)
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 14 def error_color=(error_color) @error_color = check_error_color(error_color) end
error_width=(error_width)
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 35 def error_width=(error_width) @error_width = check_number(error_width, :error_width, allow_nil: true) end
log=(val)
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 47 def log=(val) @log = check_boolean(val, :log) end
Private Instance Methods
annotate_axes(backend)
click to toggle source
Calls superclass method
# File lib/charty/plotters/bar_plotter.rb, line 90 def annotate_axes(backend) super if self.log min_value, max_value = @estimations.minmax if @plot_colors unless @conf_int.empty? min_value = [min_value, @conf_int[0]].min max_value = [max_value, @conf_int[1]].max end else ci_min = Util.filter_map(@conf_int) { |ci| ci[0] unless ci.empty? } ci_max = Util.filter_map(@conf_int) { |ci| ci[1] unless ci.empty? } min_value = [min_value, ci_min.min].min unless ci_min.empty? max_value = [max_value, ci_max.max].max unless ci_max.empty? end if min_value > 1 min_value = 0 else min_value = Math.log10(min_value).floor end max_value = Math.log10(max_value).ceil case self.orient when :v backend.set_yscale(:log) backend.set_ylim(min_value, max_value) else backend.set_xscale(:log) backend.set_xlim(min_value, max_value) end end end
check_error_color(value)
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 18 def check_error_color(value) case value when Colors::AbstractColor value when Array Colors::RGB.new(*value) when String # TODO: Use Colors.parse when it'll be available Colors::RGB.parse(value) else raise ArgumentError, "invalid value for error_color (%p for a color, a RGB tripret, or a RGB hex string)" % value end end
draw_bars(backend)
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 57 def draw_bars(backend) setup_estimations if @plot_colors.nil? bar_pos = (0 ... @estimations.length).to_a error_colors = bar_pos.map { error_color } if @conf_int.empty? ci_params = {} else ci_params = {conf_int: @conf_int, error_colors: error_colors, error_width: error_width, cap_size: cap_size} end backend.bar(bar_pos, nil, @estimations, @colors, orient, **ci_params) else bar_pos = (0 ... @estimations[0].length).to_a error_colors = bar_pos.map { error_color } offsets = color_offsets width = nested_width @color_names.each_with_index do |color_name, i| pos = bar_pos.map {|x| x + offsets[i] } colors = Array.new(@estimations[i].length) { @colors[i] } if @conf_int[i].empty? ci_params = {} else ci_params = {conf_int: @conf_int[i], error_colors: error_colors, error_width: error_width, cap_size: cap_size} end backend.bar(pos, @group_names, @estimations[i], colors, orient, label: color_name, width: width, **ci_params) end end end
estimate(estimator, data)
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 227 def estimate(estimator, data) case estimator when :count data.length when :mean data.mean else # TODO: Support other estimations raise NotImplementedError, "#{estimator} estimator is not supported yet" end end
render_plot(backend, **)
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 51 def render_plot(backend, **) draw_bars(backend) annotate_axes(backend) backend.invert_yaxis if orient == :h end
setup_estimations()
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 123 def setup_estimations if @color_names.nil? setup_estimations_with_single_color_group else setup_estimations_with_multiple_color_groups end end
setup_estimations_with_multiple_color_groups()
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 171 def setup_estimations_with_multiple_color_groups estimations = Array.new(@color_names.length) { [] } conf_int = Array.new(@color_names.length) { [] } @plot_data.each_with_index do |group_data, i| @color_names.each_with_index do |color_name, j| if @plot_colors[i].length == 0 estimations[j] << Float::NAN unless ci.nil? conf_int[j] << [Float::NAN, Float::NAN] end next end color_mask = @plot_colors[i].eq(color_name) if @plot_units.nil? begin stat_data = group_data[color_mask].drop_na rescue @plot_data.each_with_index {|pd, k| p k => pd } @plot_colors.each_with_index {|pc, k| p k => pc } raise end unit_data = nil else # TODO: Support units end estimation = if stat_data.size == 0 Float::NAN else estimate(estimator, stat_data) end estimations[j] << estimation unless ci.nil? if stat_data.size < 2 conf_int[j] << [Float::NAN, Float::NAN] next end if ci == :sd sd = stat_data.stdev conf_int[j] << [estimation - sd, estimation + sd] else conf_int[j] << Statistics.bootstrap_ci(stat_data, ci, func: estimator, n_boot: n_boot, units: unit_data, random: random) end end end end @estimations = estimations @conf_int = conf_int end
setup_estimations_with_single_color_group()
click to toggle source
# File lib/charty/plotters/bar_plotter.rb, line 131 def setup_estimations_with_single_color_group estimations = [] conf_int = [] @plot_data.each do |group_data| # Single color group if @plot_units.nil? stat_data = group_data.drop_na unit_data = nil else # TODO: Support units end estimation = if stat_data.size == 0 Float::NAN else estimate(estimator, stat_data) end estimations << estimation unless ci.nil? if stat_data.size < 2 conf_int << [Float::NAN, Float::NAN] next end if ci == :sd sd = stat_data.stdev conf_int << [estimation - sd, estimation + sd] else conf_int << Statistics.bootstrap_ci(stat_data, ci, func: estimator, n_boot: n_boot, units: unit_data, random: random) end end end @estimations = estimations @conf_int = conf_int end