class GnuplotRB::Plot

Class corresponding to simple 2D visualisation.

Notebooks

Options

All possible options are exaplained in gnuplot docs (pp. 105-190).

Several common ones:

Every option may be passed to constructor in order to create plot with it.

Methods options(several: options, …) and bunch of option_name(only_an: option) such as xrange, using, polar etc create new Plot object based on existing but with a new options.

Methods with the same names ending with '!' or '=' ('plot.xrange!(1..3)', 'plot.title = “New title”') are destructive and modify state of existing object just as “Array#sort!” do with Array object. See notebooks for examples.

Attributes

datasets[R]

Array of datasets which are plotted by this object.

Public Class Methods

new(*datasets) { |self| ... } click to toggle source

@param *datasets [Sequence of Dataset or Array] either instances of Dataset class or

"[data, **dataset_options]"" arrays

@param options [Hash] see Plot top level doc for options examples

# File lib/gnuplotrb/plot.rb, line 48
def initialize(*datasets)
  # had to relace **options arg with this because in some cases
  # Daru::DataFrame was mentioned as hash and added to options
  # instead of plots
  @options = Hamster::Hash.empty
  if datasets[-1].is_a?(Hamster::Hash) || datasets[-1].is_a?(Hash)
    @options = Hamster::Hash[datasets[-1]]
    datasets = datasets[0..-2]
  end
  @datasets = parse_datasets_array(datasets)
  @cmd = 'plot '
  OptionHandling.validate_terminal_options(@options)
  yield(self) if block_given?
end

Public Instance Methods

<<(*datasets)
Alias for: add_datasets
[](*args) click to toggle source

The same as datasets[*args]

# File lib/gnuplotrb/plot.rb, line 241
def [](*args)
  @datasets[*args]
end
[]=(position = 0, dataset)
Alias for: replace_dataset!
add_dataset(*datasets)
Alias for: add_datasets
add_dataset!(*datasets)
Alias for: add_datasets!
add_datasets(*datasets) click to toggle source

Create new Plot object where given datasets will be inserted into dataset list before given position (position = 0 by default).

@param position [Integer] position of dataset BEFORE which datasets will be placed.

0 by default.

@param *datasets [ Sequence of Dataset or Array] datasets to insert @example

sinx = Plot.new('sin(x)')
sinx_and_cosx_with_expx = sinx.add(['cos(x)'], ['exp(x)'])

cosx_and_sinx = sinx << ['cos(x)']
# sinx IS NOT affected in both cases
# File lib/gnuplotrb/plot.rb, line 178
def add_datasets(*datasets)
  datasets.map! { |ds| ds.is_a?(Numeric) ? ds : dataset_from_any(ds) }
  # first element is position where to add datasets
  datasets.unshift(0) unless datasets[0].is_a?(Numeric)
  self.class.new(@datasets.insert(*datasets), @options)
end
Also aliased as: add_dataset, <<
add_datasets!(*datasets) click to toggle source

Updates existing Plot object by inserting given datasets into dataset list before given position (position = 0 by default).

@param position [Integer] position of dataset BEFORE which datasets will be placed.

0 by default.

@param *datasets [ Sequence of Dataset or Array] datasets to insert @example

sinx = Plot.new('sin(x)')
sinx.add!(['cos(x)'], ['exp(x)'])
# sinx IS affected
# File lib/gnuplotrb/plot.rb, line 199
def add_datasets!(*datasets)
  datasets.map! { |ds| ds.is_a?(Numeric) ? ds : dataset_from_any(ds) }
  # first element is position where to add datasets
  datasets.unshift(0) unless datasets[0].is_a?(Numeric)
  @datasets = @datasets.insert(*datasets)
  self
end
Also aliased as: add_dataset!
plot(term = nil, multiplot_part: false, **options) click to toggle source

Output plot to term (if given) or to this plot's own terminal.

@param term [Terminal] Terminal object to plot to @param :multiplot_part [Boolean] true if this plot is part of a multiplot. For inner use! @param options [Hash] see options in Plot top level doc.

Options passed here have priority over already existing.

@return [Plot] self

# File lib/gnuplotrb/plot.rb, line 71
def plot(term = nil, multiplot_part: false, **options)
  fail ArgumentError, 'Empty plots are not supported!' if @datasets.empty?
  inner_opts = if multiplot_part
                 @options.merge(options).reject { |key, _| [:term, :output].include?(key) }
               else
                 @options.merge(options)
               end
  terminal = term || (inner_opts[:output] ? Terminal.new : own_terminal)
  ds_string = @datasets.map { |dataset| dataset.to_s(terminal) }.join(' , ')
  full_command = @cmd + ds_string
  terminal.set(inner_opts).stream_puts(full_command).unset(inner_opts.keys)
  if inner_opts[: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?(inner_opts[:output])
  end
  self
end
Also aliased as: replot
remove_dataset(position = -1) click to toggle source

Create new Plot object where dataset at given position will be removed from dataset list.

@param position [Integer] position of dataset that should be

removed (by default last dataset is removed)

@example

sinx_and_cosx = Plot.new('sin(x)', 'cos(x)')
sinx = sinx_and_cosx.remove_dataset
cosx = sinx_and_cosx.remove_dataset(0)
# sinx_and_cosx IS NOT affected in both cases
# File lib/gnuplotrb/plot.rb, line 220
def remove_dataset(position = -1)
  self.class.new(@datasets.delete_at(position), @options)
end
remove_dataset!(position = -1) click to toggle source

Updates existing Plot object by removing dataset at given position.

@param position [Integer] position of dataset that should be

removed (by default last dataset is removed)

@example

sinx_and_cosx = Plot.new('sin(x)', 'cos(x)')
sinx_and_cosx!.remove_dataset
sinx_and_cosx!.remove_dataset
# sinx_and_cosx IS affected and now is empty
# File lib/gnuplotrb/plot.rb, line 234
def remove_dataset!(position = -1)
  @datasets = @datasets.delete_at(position)
  self
end
replace_dataset(position = 0, dataset) click to toggle source

Create new Plot object where dataset at position will be replaced with the given one.

@param position [Integer] position of dataset which you need to replace

(by default first dataset is replaced)

@param dataset [Dataset, Array] dataset to replace the old one. You can also

give here "[data, **dataset_options]"" array from which Dataset may be created.

@example

sinx = Plot.new('sin(x)')
cosx = sinx.replace_dataset(['cos(x)'])
# sinx IS NOT affected
# File lib/gnuplotrb/plot.rb, line 141
def replace_dataset(position = 0, dataset)
  self.class.new(@datasets.set(position, dataset_from_any(dataset)), @options)
end
replace_dataset!(position = 0, dataset) click to toggle source

Updates existing Plot object by replacing dataset at position with the given one.

@param position [Integer] position of dataset which you need to replace

(by default first dataset is replaced)

@param dataset [Dataset, Array] dataset to replace the old one. You can also

give here "[data, **dataset_options]"" array from which Dataset may be created.

@example

sinx = Plot.new('sin(x)')
sinx.replace_dataset!(['cos(x)'])
# sinx IS affected
# File lib/gnuplotrb/plot.rb, line 157
def replace_dataset!(position = 0, dataset)
  @datasets = @datasets.set(position, dataset_from_any(dataset))
  self
end
Also aliased as: []=
replot(term = nil, multiplot_part: false, **options)
Alias for: plot
update_dataset(position = 0, data: nil, **options) click to toggle source

Create new Plot object where dataset at position will be replaced with the new one created from it by updating.

@param position [Integer] position of dataset which you need to update

(by default first dataset is updated)

@param data [#to_gnuplot_points] data to update dataset with @param options [Hash] options to update dataset with, see Dataset top level doc

@example

updated_plot = plot.update_dataset(data: [x1,y1], title: 'After update')
# plot IS NOT affected (if dataset did not store data in a file)
# File lib/gnuplotrb/plot.rb, line 106
def update_dataset(position = 0, data: nil, **options)
  old_ds = @datasets[position]
  new_ds = old_ds.update(data, options)
  new_ds.equal?(old_ds) ? self : replace_dataset(position, new_ds)
end
update_dataset!(position = 0, data: nil, **options) click to toggle source

Updates existing Plot object by replacing dataset at position with the new one created from it by updating.

@param position [Integer] position of dataset which you need to update

(by default first dataset is updated)

@param data [#to_gnuplot_points] data to update dataset with @param options [Hash] options to update dataset with, see Dataset top level doc

@example

plot.update_dataset!(data: [x1,y1], title: 'After update')
# plot IS affected anyway
# File lib/gnuplotrb/plot.rb, line 124
def update_dataset!(position = 0, data: nil, **options)
  @datasets[position].update!(data, options)
  self
end

Private Instance Methods

dataset_from_any(source) click to toggle source

Check if given args is a dataset and returns it. Creates new dataset from given args otherwise.

# File lib/gnuplotrb/plot.rb, line 265
def dataset_from_any(source)
  ds = case source
       # when initialized with dataframe (it passes here several vectors)
       when (defined?(Daru) ? Daru::Vector : nil)
         Dataset.new(source)
       when Dataset
         source.clone
       else
         Dataset.new(*source)
       end
  data = source.is_a?(Array) ? source[0] : source
  provide_with_datetime_format(data, ds.using)
  ds
end
new_with_options(options) click to toggle source

Creates new Plot with existing data and given options.

# File lib/gnuplotrb/plot.rb, line 296
def new_with_options(options)
  self.class.new(@datasets, options)
end
parse_datasets_array(datasets) click to toggle source

Parses given array and returns Hamster::Vector of Datasets

# File lib/gnuplotrb/plot.rb, line 282
def parse_datasets_array(datasets)
  case datasets[0]
  when Hamster::Vector
    datasets[0]
  when (defined?(Daru) ? Daru::DataFrame : nil)
    set_name_from_daru_dataframe(datasets[0])
    Hamster::Vector.new(datasets[0].map { |ds| dataset_from_any(ds) })
  else
    Hamster::Vector.new(datasets.map { |ds| dataset_from_any(ds) })
  end
end
provide_with_datetime_format(data, using) click to toggle source

Checks several conditions and set options needed to handle DateTime indexes properly.

# File lib/gnuplotrb/plot.rb, line 250
def provide_with_datetime_format(data, using)
  return unless defined?(Daru)
  return unless data.is_a?(Daru::DataFrame) || data.is_a?(Daru::Vector)
  return unless data.index.first.is_a?(DateTime)
  return if using[0..1] != '1:'
  @options = Hamster::Hash.new(
    xdata: 'time',
    timefmt: '%Y-%m-%dT%H:%M:%S',
    format_x: '%d\n%b\n%Y'
  ).merge(@options)
end
set_name_from_daru_dataframe(dataframe) click to toggle source
# File lib/gnuplotrb/plot.rb, line 300
def set_name_from_daru_dataframe(dataframe)
  self.title = dataframe.name unless title
end