module Digiproc::Plottable::ClassMethods

Contains generic plotting helpers which can be extended to make more specific plotting helpers, or can be used in another class to extend their functionality. Digiproc::Plottable does extend self::ClassMethods, so they can be used as standalone plotting functions using Digiproc::Plottable.iplot() { |g| … } or Digiproc::Plottable.qplot(…)

Public Instance Methods

iplot(xsteps: 4) { |g| ... } click to toggle source

Will yield g and allow the caller to define the plot as they wish. It does very little beforehand to setup the plot

# File lib/concerns/plottable.rb, line 76
def iplot(xsteps: 4)
    g = Gruff::Line.new('1000x1000')
    g.theme = Digiproc::Plottable::Styles::BLUESCALE
    g.line_width = 2
    g.dot_radius = 0.1
    yield g 
    #must insert data :name, data_arr
    #or dataxy :name, x_arr, y_arr

    # Go through each dataset,
    #If there are x values, get max and min
    #If there are not, get the length of the data
    #If labels are not inserted by user, do:
    #  get range of largest dataset
    #  label at 0, 0.25*len, 0.5*len, 0.75*len, len
    return g 
end
qplot(x: nil ,y: nil , data: nil, data_name: "data", xyname: "data",filename: " { |g| ... } click to toggle source

Used by Digiproc::QuickPlot.

qplot(x: Array[Numeric], y: Array[Numeric], data: Array[Numeric], data_name: String, xyname: String, filename: String, path: String, xsteps: Integer, label_map: ->(Float) returns Float)  #=> returns a plot at the entered directory or './plots' by default (ensure directory exists)

x and y OR data must exist to make a plot. `label_map` is used to map the index of the data (or the x value at that point if using xy) to an appropriate label. For example if the x values are between 1 and 10 but data.length is 10000, your label_map could be:

label_map = ->(index_val){ return index_val / 1000.0 }

The frequency of labels will be determined by `xsteps`

# File lib/concerns/plottable.rb, line 104
def qplot(x: nil ,y: nil , data: nil, data_name: "data", xyname: "data",filename: "#{self}_plot", path: "./plots/", xsteps: 4, label_map: nil)
    raise ArgumentError.new("Either x and y or data must exist") if data.nil? and (x.nil? or y.nil?)
    data = data
    raise TypeError.new("Data must be an array, not a #{data.class}") if data and not data.is_a? Array
    raise TypeError.new("X and Y must be arrays, not #{x.class}, #{y.class}") if (!!x and !!y) and not (x.is_a?(Array) and y.is_a?(Array))
    raise ArgumentError.new("X and Y must be the same size") if (!!x and !!y) and (x.length != y.length)
    g = Gruff::Line.new('1000x1000')
    g.theme = Styles::BLUESCALE
    g.line_width = 2.5
    g.dot_radius = 0.1
    # g.minimum_x_value = 0
    g.data data_name, data if !!data
    g.dataxy xyname, x, y if !!x and !!y
    xmax = !!data ? data.length : x.max
    xmin = !!data ? 0 : x.min
    increment_label = (xmax - xmin) / xsteps.to_f
    datalength = !!data ? data.length : x.length
    increment_datapoints = (datalength.to_f / xsteps).round
    labels = {}
    for i in 0..xsteps do
        datapoint_location = i * increment_datapoints
        datapoint_location -= 1 if datapoint_location > (datalength - 1)
        label_val = label_map.nil? ? (i * increment_label).round(2) : label_map.call((i * increment_label)).round(2)
        labels[datapoint_location] = label_val
    end
    g.labels = labels
    g.show_vertical_markers = false
    yield g
    g.write(path + filename + '.png')
end