class GnuplotRB::Multiplot
Multiplot
allows to place several plots on one layout. It's usage is covered in multiplot notebook.
Options¶ ↑
Most of Multiplot
options are the same as in Plot
so one can also set any options related to Plot
and they will be considered by all nested plots (if they does not override it with their own values).
There are only 2 specific options:
-
title - set title for the whole layout (above all the plots)
-
layout - set layout size, examples:
{ layout : [1, 3] } # 3 plots, 1 row, 3 columns { layout : [2, 2] } # 4 plots, 2 rows, 2 columns
Attributes
@return [Array] Array
of plots contained by this object
Public Class Methods
@param plots [Plot, Splot
, Hamster::Vector] Hamster vector (or just sequence) with Plot
or Splot objects which should be placed on this multiplot layout
@param options [Hash] see options in top class docs
# File lib/gnuplotrb/multiplot.rb, line 27 def initialize(*plots, **options) @plots = plots[0].is_a?(Hamster::Vector) ? plots[0] : Hamster::Vector.new(plots) @options = Hamster::Hash[options] OptionHandling.validate_terminal_options(@options) yield(self) if block_given? end
Public Instance Methods
Equal to plots[*args]
# File lib/gnuplotrb/multiplot.rb, line 210 def [](*args) @plots[*args] end
Create new Multiplot
with given plots added before plot at given position. (by default it adds plot at the front).
@param position [Integer] position of plot which you need to replace
(by default first plot is replace)
@param plots [Sequence of Plot
or Splot] plots you want to add @return [Multiplot] self @example
mp = Multiplot.new(Plot.new('sin(x)'), Plot.new('cos(x)'), layout: [2,1]) enlarged_mp = mp.add_plots(Plot.new('exp(x)')).layout([3,1]) # mp IS NOT affected
# File lib/gnuplotrb/multiplot.rb, line 150 def add_plots(*plots) plots.unshift(0) unless plots[0].is_a?(Numeric) self.class.new(@plots.insert(*plots), @options) end
Destructive version of add_plots
.
@return [Multiplot] self @example
mp = Multiplot.new(Plot.new('sin(x)'), Plot.new('cos(x)'), layout: [2,1]) mp.add_plots!(Plot.new('exp(x)')).layout([3,1]) # mp IS affected
# File lib/gnuplotrb/multiplot.rb, line 167 def add_plots!(*plots) plots.unshift(0) unless plots[0].is_a?(Numeric) @plots = @plots.insert(*plots) self end
Output all the plots to term (if given) or to this Multiplot's own terminal.
@param term [Terminal] Terminal
to plot to @param multiplot_part [Boolean] placeholder, does not really needed and should not be used @param options [Hash] see options in top class docs.
Options passed here have priority over already set.
@return [Multiplot] self
# File lib/gnuplotrb/multiplot.rb, line 42 def plot(term = nil, multiplot_part: false, **options) plot_options = mix_options(options) do |plot_opts, mp_opts| plot_opts.merge(multiplot: mp_opts.to_h) end terminal = term || (plot_options[:output] ? Terminal.new : own_terminal) multiplot(terminal, plot_options) if plot_options[:output] # guaranteed wait for plotting to finish terminal.close unless term # not guaranteed wait for plotting to finish # work bad with terminals like svg and html sleep 0.01 until File.size?(plot_options[:output]) end self end
Create new Multiplot
without plot at given position (by default last plot is removed).
@param position [Integer] position of plot which you need to remove
(by default last plot is removed)
@return [Multiplot] self @example
mp = Multiplot.new(Plot.new('sin(x)'), Plot.new('cos(x)'), layout: [2,1]) mp_with_only_cos = mp.remove_plot(0) # mp IS NOT affected
# File lib/gnuplotrb/multiplot.rb, line 187 def remove_plot(position = -1) self.class.new(@plots.delete_at(position), @options) end
Destructive version of remove_plot
.
@return [Multiplot] self @example
mp = Multiplot.new(Plot.new('sin(x)'), Plot.new('cos(x)'), layout: [2,1]) mp.remove_plot!(0) # mp IS affected
# File lib/gnuplotrb/multiplot.rb, line 201 def remove_plot!(position = -1) @plots = @plots.delete_at(position) self end
Create new Multiplot
object where plot (Plot
or Splot
object) at position will be replaced with the given one.
@param position [Integer] position of plot which you need to replace
(by default first plot is replace)
@param plot [Plot, Splot] replacement @return [Multiplot] self @example
mp = Multiplot.new(Plot.new('sin(x)'), Plot.new('cos(x)'), layout: [2,1]) mp_with_replaced_plot = mp.replace_plot(Plot.new('exp(x)', title: 'exp instead of sin')) # mp IS NOT affected
# File lib/gnuplotrb/multiplot.rb, line 116 def replace_plot(position = 0, plot) self.class.new(@plots.set(position, plot), @options) end
Destructive version of replace_plot
.
@return [Multiplot] self @example
mp = Multiplot.new(Plot.new('sin(x)'), Plot.new('cos(x)'), layout: [2,1]) mp.replace_plot!(Plot.new('exp(x)', title: 'exp instead of sin')) # mp IS affected
# File lib/gnuplotrb/multiplot.rb, line 130 def replace_plot!(position = 0, plot) @plots = @plots.set(position, plot) self end
Create new updated Multiplot
object where plot (Plot
or Splot
object) at position will be replaced with the new one created from it by updating. To update a plot you can pass some options for it or a block, that should take existing plot (with new options if you gave them) and return a plot too.
Method yields new created Plot
or Splot
to allow you update it manually.
@param position [Integer] position of plot which you need to update
(by default first plot is updated)
@param options [Hash] options to set into updated plot @return [Multiplot] self @yieldparam plot [Plot, Splot] a new plot @yieldreturn [Plot, Splot] changed plot @example
mp = Multiplot.new(Plot.new('sin(x)'), Plot.new('cos(x)'), layout: [2,1]) updated_mp = mp.update_plot(title: 'Sin(x) and Exp(x)') { |sinx| sinx.add!('exp(x)') } # mp IS NOT affected
# File lib/gnuplotrb/multiplot.rb, line 78 def update_plot(position = 0, **options) return self unless block_given? if options.empty? replacement = @plots[position].options(options) replacement = yield(replacement) if block_given? replace_plot(position, replacement) end
Destructive version of update_plot
.
@return [Multiplot] self @example
Multiplot.new(Plot.new('sin(x)'), Plot.new('cos(x)'), layout: [2,1]) mp.update_plot!(title: 'Sin(x) and Exp(x)') { |sinx| sinx.add!('exp(x)') } # mp IS affected
# File lib/gnuplotrb/multiplot.rb, line 95 def update_plot!(position = 0, **options) return self unless block_given? if options.empty? replacement = @plots[position].options!(options) yield(replacement) if block_given? self end
Private Instance Methods
Default options to be used for that plot
# File lib/gnuplotrb/multiplot.rb, line 218 def default_options { layout: [2, 2], title: 'Multiplot' } end
Takes all options and splits them into specific and others. Requires a block where this two classes should be mixed.
# File lib/gnuplotrb/multiplot.rb, line 255 def mix_options(options) all_options = @options.merge(options) specific_options, plot_options = all_options.partition { |key, _value| specific_option?(key) } yield(plot_options, default_options.merge(specific_options)) end
Just a part of plot
.
# File lib/gnuplotrb/multiplot.rb, line 263 def multiplot(terminal, options) terminal.set(options) @plots.each { |graph| graph.plot(terminal, multiplot_part: true) } terminal.unset(options.keys) end
Create new Multiplot
object with the same set of plots and given options. Used in OptionHandling
module.
# File lib/gnuplotrb/multiplot.rb, line 240 def new_with_options(options) self.class.new(@plots, options) end
This plot have some specific options which should be handled different way than others. Here are keys of this options.
# File lib/gnuplotrb/multiplot.rb, line 229 def specific_keys %w( title layout ) end
Check if given options corresponds to multiplot. Uses specific_keys
to check.
# File lib/gnuplotrb/multiplot.rb, line 247 def specific_option?(key) specific_keys.include?(key.to_s) end