Class: RVGP::Plot
- Inherits:
-
Object
- Object
- RVGP::Plot
- Defined in:
- lib/rvgp/plot.rb,
lib/rvgp/plot/gnuplot.rb,
lib/rvgp/plot/google-drive/sheet.rb,
lib/rvgp/plot/google-drive/output_csv.rb,
lib/rvgp/plot/google-drive/output_google_sheets.rb
Overview
This class assembles grids into a series of plots, given a plot specification yaml. Once a grid is assembled, it’s dispatched to a driver (GoogleDrive or Gnuplot) for rendering. Here’s an example plot specification, included in the default project build as wealth-growth.yml, as created by the new_project command: “‘ title: “Wealth Growth (%year)” glob: “%year-wealth-growth.csv” grid_hacks:
store_cell: !!proc >
(cell) ? cell.to_f.abs : nil
google:
chart_type: area
axis:
left: "Amount"
bottom: "Date"
gnuplot:
chart_type: area
domain: monthly
axis:
left: "Amount"
bottom: "Date"
additional_lines: |+
set xtics scale 0 rotate by 45 offset -1.4,-1.4
set key title ' '
set style fill transparent solid 0.7 border
“‘
The yaml file is required to have :title and :glob parameters. Additionally, the following parameter groups are supported: :grid_hacks, :gnuplot, and :google.
The :gnuplot section of this file, is merged with the contents of default.yml, and passed to the Gnuplot constructor. See the Gnuplot::Plot#initialize method for more details on what parameters are supported in this section. NOTE: Depending on the kind of chart being specified, some initialize options are specific to the chart being built, and those options will be documented in the constructor for that specific chart. ie: Gnuplot::AreaChart#initialize or Gnuplot::ColumnAndLineChart#initialize.
The :google section of this file, is provided to GoogleDrive::Sheet#initialize. See this method for details on supported options.
The :grid_hacks section of this file, contains miscellaneous hacks to the dataset. These include: :keystone, :store_cell, :select_rows, :sort_rows_by, :sort_columns_by, :truncate_rows, :switch_rows_columns, and :truncate_columns. These options are documented in: Utilities::GridQuery#initialize and Utilities::GridQuery#to_grid.
Defined Under Namespace
Modules: Gnuplot, GoogleDrive Classes: InvalidYamlGlob, MissingYamlAttribute
Constant Summary collapse
- REQUIRED_FIELDS =
The required keys, expected to exist in the plot yaml
%i[glob title].freeze
- GNUPLOT_RESOURCES_PATH =
The path to rvgp’s ‘default’ include file search path. Any ‘!!include’ directives encountered in the plot yaml, will search this location for targets.
[RVGP::Gem.root, '/resources/gnuplot'].join
Instance Attribute Summary collapse
-
#glob ⇒ String
readonly
A string containing wildcards, used to match input grids in the filesystem.
-
#path ⇒ String
readonly
A path to the location of the input yaml, as provided to #initialize.
-
#yaml ⇒ RVGP::Utilities::Yaml
readonly
The yaml object, containing the parameters of this plot.
Class Method Summary collapse
-
.all(plot_directory_path) ⇒ Array<RVGP::Plot>
Return all the plot objects, initialized from the yaml files in the plot_directory_path.
-
.glob_variants(glob, corpus, pair_values = {}) ⇒ Array<Hash<Symbol,Object>>
This returns what plot variants are possible, given a glob, when matched against the provided file names.
Instance Method Summary collapse
-
#column_titles(variant_name) ⇒ Array<String>
Return the column titles, on the plot for a given variant.
-
#gnuplot(name) ⇒ RVGP::Plot::Gnuplot::Plot
Return the gnuplot object, for a given variant.
-
#google_options ⇒ Hash
Return the google plot options, from the yaml of this plot.
-
#grid(variant_name) ⇒ Array<Array<Object>>
Generate and return, a plot grid, for the given variant.
-
#initialize(path) ⇒ Plot
constructor
Create a plot, from a specification yaml.
-
#output_file(name, ext) ⇒ String
Generate an output file path, for the given variant.
-
#script(name) ⇒ String
Return the rendered gnuplot code, for a given variant.
-
#series(variant_name) ⇒ Array<Array<Object>>
Return the portion of the grid, containing series labels, and their data.
-
#show(name) ⇒ void
Execute the rendered gnuplot code, for a given variant.
-
#title(variant_name) ⇒ String
The plot title, of the given variant.
-
#variant_files(variant_name) ⇒ Array<String>
This method returns only the :files parameter, of the #variants return.
-
#variants(name = nil) ⇒ Hash<Symbol, Object>
In the case that a name is provided, limit the return to the variant of the provided :name.
-
#write!(name) ⇒ void
Write the gnuplot code, for a given variant, to the :output_file.
Constructor Details
#initialize(path) ⇒ Plot
Create a plot, from a specification yaml
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/rvgp/plot.rb', line 97 def initialize(path) @path = path @yaml = RVGP::Utilities::Yaml.new path, [RVGP.app.config.project_path, GNUPLOT_RESOURCES_PATH] missing_attrs = REQUIRED_FIELDS.reject { |f| yaml.key? f } raise MissingYamlAttribute, yaml.path, missing_attrs unless missing_attrs.empty? @glob = yaml[:glob] if yaml.key? :glob raise InvalidYamlGlob, yaml.path unless /%\{year\}/.match glob grids_corpus = Dir[RVGP.app.config.build_path('grids/*')] @variants ||= self.class.glob_variants(glob, grids_corpus) + self.class.glob_variants(glob, grids_corpus, year: 'all') @title = yaml[:title] if yaml.key? :title end |
Instance Attribute Details
#glob ⇒ String (readonly)
A string containing wildcards, used to match input grids in the filesystem. This parameter is expected to be found inside the yaml, and will generally look something like: “%{year}-wealth-growth.csv” or “%{year}-property-incomes-%{property}.csv”. The variables which are supported, include ‘the year’ of a plot, as well as whatever variables are defined in a plot’s glob_variants (‘property’, as was the case above.) glob_variants are output by grids, and detected in the filenames those grids produce by the glob_variants method.
63 64 65 |
# File 'lib/rvgp/plot.rb', line 63 def glob @glob end |
#path ⇒ String (readonly)
A path to the location of the input yaml, as provided to #initialize
63 64 65 |
# File 'lib/rvgp/plot.rb', line 63 def path @path end |
#yaml ⇒ RVGP::Utilities::Yaml (readonly)
The yaml object, containing the parameters of this plot
63 64 65 |
# File 'lib/rvgp/plot.rb', line 63 def yaml @yaml end |
Class Method Details
.all(plot_directory_path) ⇒ Array<RVGP::Plot>
Return all the plot objects, initialized from the yaml files in the plot_directory_path
275 276 277 |
# File 'lib/rvgp/plot.rb', line 275 def self.all(plot_directory_path) Dir.glob(format('%s/*.yml', plot_directory_path)).map { |path| new path } end |
.glob_variants(glob, corpus, pair_values = {}) ⇒ Array<Hash<Symbol,Object>>
This returns what plot variants are possible, given a glob, when matched against the provided file names. If pair_values contains key: value combinations, then, any of the returned variants will be sorted under the key:value provided . (Its really just meant for year: ‘all’, atm..)
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/rvgp/plot.rb', line 244 def self.glob_variants(glob, corpus, pair_values = {}) variant_names = glob.scan(/%\{([^ }]+)/).flatten.map(&:to_sym) glob_vars = variant_names.to_h { |key| [key, '(.+)'] } variant_matcher = Regexp.new format(glob, glob_vars) corpus.each_with_object([]) do |file, ret| matches = variant_matcher.match File.basename(file) if matches pairs = variant_names.map.with_index do |key, i| [key, pair_values.key?(key.to_sym) ? pair_values[key] : matches[i + 1]] end.to_h pair_i = ret.find_index { |variant| variant[:pairs] == pairs } if pair_i ret[pair_i][:files] << file else ret << { name: File.basename(glob % pairs, '.*'), pairs: pairs, files: [file] } end end ret end.compact end |
Instance Method Details
#column_titles(variant_name) ⇒ Array<String>
Return the column titles, on the plot for a given variant
188 189 190 |
# File 'lib/rvgp/plot.rb', line 188 def column_titles(variant_name) grid(variant_name)[0] end |
#gnuplot(name) ⇒ RVGP::Plot::Gnuplot::Plot
Return the gnuplot object, for a given variant
208 209 210 211 |
# File 'lib/rvgp/plot.rb', line 208 def gnuplot(name) @gnuplots ||= {} @gnuplots[name] ||= RVGP::Plot::Gnuplot::Plot.new title(name), grid(name), end |
#google_options ⇒ Hash
Return the google plot options, from the yaml of this plot.
201 202 203 |
# File 'lib/rvgp/plot.rb', line 201 def @google_options = yaml[:google] if yaml.key? :google end |
#grid(variant_name) ⇒ Array<Array<Object>>
Generate and return, a plot grid, for the given variant.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/rvgp/plot.rb', line 152 def grid(variant_name) @grid ||= {} @grid[variant_name] ||= begin gopts = {} rvopts = { store_cell: if grid_hacks.key?(:store_cell) ->(cell) { grid_hacks[:store_cell].call cell: cell } else ->(cell) { cell ? cell.to_f : nil } end } # Grid Reader Options: rvopts[:keystone] = grid_hacks[:keystone] if grid_hacks.key? :keystone if grid_hacks.key? :select_rows rvopts[:select_rows] = ->(name, data) { grid_hacks[:select_rows].call name: name, data: data } end # to_grid Options gopts[:truncate_rows] = grid_hacks[:truncate_rows].to_i if grid_hacks.key? :truncate_rows gopts[:truncate_columns] = grid_hacks[:truncate_columns].to_i if grid_hacks.key? :truncate_columns gopts[:switch_rows_columns] = grid_hacks[:switch_rows_columns] if grid_hacks.key? :switch_rows_columns gopts[:sort_rows_by] = ->(row) { grid_hacks[:sort_rows_by].call row: row } if grid_hacks.key? :sort_rows_by if grid_hacks.key? :sort_columns_by gopts[:sort_cols_by] = ->(column) { grid_hacks[:sort_columns_by].call column: column } end RVGP::Utilities::GridQuery.new(variant_files(variant_name), rvopts).to_grid(gopts) end end |
#output_file(name, ext) ⇒ String
Generate an output file path, for the given variant. Typically this is a .csv grid, in the build/grids subdirectory of your project folder.
145 146 147 |
# File 'lib/rvgp/plot.rb', line 145 def output_file(name, ext) RVGP.app.config.build_path format('plots/%<name>s.%<ext>s', name: name, ext: ext) end |
#script(name) ⇒ String
Return the rendered gnuplot code, for a given variant
216 217 218 |
# File 'lib/rvgp/plot.rb', line 216 def script(name) gnuplot(name).script end |
#series(variant_name) ⇒ Array<Array<Object>>
Return the portion of the grid, containing series labels, and their data.
195 196 197 |
# File 'lib/rvgp/plot.rb', line 195 def series(variant_name) grid(variant_name)[1..] end |
#show(name) ⇒ void
This method returns an undefined value.
Execute the rendered gnuplot code, for a given variant. Typically, this opens a gnuplot window.
224 225 226 |
# File 'lib/rvgp/plot.rb', line 224 def show(name) gnuplot(name).execute! end |
#title(variant_name) ⇒ String
The plot title, of the given variant
136 137 138 |
# File 'lib/rvgp/plot.rb', line 136 def title(variant_name) @title % variants(variant_name)[:pairs] end |
#variant_files(variant_name) ⇒ Array<String>
This method returns only the :files parameter, of the #variants return.
129 130 131 |
# File 'lib/rvgp/plot.rb', line 129 def variant_files(variant_name) variants(variant_name)[:files] end |
#variants(name = nil) ⇒ Hash<Symbol, Object>
In the case that a name is provided, limit the return to the variant of the provided :name. If no name is provided, all variants in this plot are returned. Variants are determined by the yaml parameter :glob, as applied to the grids found in the build/grids/* path.
122 123 124 |
# File 'lib/rvgp/plot.rb', line 122 def variants(name = nil) name ? @variants.find { |v| v[:name] == name } : @variants end |
#write!(name) ⇒ void
This method returns an undefined value.
Write the gnuplot code, for a given variant, to the :output_file
231 232 233 |
# File 'lib/rvgp/plot.rb', line 231 def write!(name) File.write output_file(name, 'gpi'), gnuplot(name).script end |