daru 0.1.3.1 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +2 -1
- data/.rspec_formatter.rb +33 -0
- data/.rubocop.yml +26 -2
- data/History.md +38 -0
- data/README.md +22 -13
- data/Rakefile +50 -2
- data/benchmarks/csv_reading.rb +22 -0
- data/daru.gemspec +9 -2
- data/lib/daru.rb +36 -4
- data/lib/daru/accessors/array_wrapper.rb +6 -1
- data/lib/daru/accessors/dataframe_by_row.rb +10 -2
- data/lib/daru/accessors/gsl_wrapper.rb +1 -3
- data/lib/daru/accessors/nmatrix_wrapper.rb +9 -0
- data/lib/daru/category.rb +935 -0
- data/lib/daru/core/group_by.rb +29 -38
- data/lib/daru/core/merge.rb +186 -145
- data/lib/daru/core/query.rb +22 -11
- data/lib/daru/dataframe.rb +976 -885
- data/lib/daru/date_time/index.rb +166 -166
- data/lib/daru/date_time/offsets.rb +66 -77
- data/lib/daru/formatters/table.rb +54 -0
- data/lib/daru/helpers/array.rb +40 -0
- data/lib/daru/index.rb +476 -73
- data/lib/daru/io/io.rb +66 -45
- data/lib/daru/io/sql_data_source.rb +33 -62
- data/lib/daru/iruby/helpers.rb +38 -0
- data/lib/daru/iruby/templates/dataframe.html.erb +52 -0
- data/lib/daru/iruby/templates/dataframe_mi.html.erb +58 -0
- data/lib/daru/iruby/templates/multi_index.html.erb +12 -0
- data/lib/daru/iruby/templates/vector.html.erb +27 -0
- data/lib/daru/iruby/templates/vector_mi.html.erb +36 -0
- data/lib/daru/maths/arithmetic/dataframe.rb +16 -18
- data/lib/daru/maths/arithmetic/vector.rb +4 -6
- data/lib/daru/maths/statistics/dataframe.rb +8 -15
- data/lib/daru/maths/statistics/vector.rb +120 -98
- data/lib/daru/monkeys.rb +12 -40
- data/lib/daru/plotting/gruff.rb +3 -0
- data/lib/daru/plotting/gruff/category.rb +49 -0
- data/lib/daru/plotting/gruff/dataframe.rb +91 -0
- data/lib/daru/plotting/gruff/vector.rb +57 -0
- data/lib/daru/plotting/nyaplot.rb +3 -0
- data/lib/daru/plotting/nyaplot/category.rb +34 -0
- data/lib/daru/plotting/nyaplot/dataframe.rb +187 -0
- data/lib/daru/plotting/nyaplot/vector.rb +46 -0
- data/lib/daru/vector.rb +694 -421
- data/lib/daru/version.rb +1 -1
- data/profile/_base.rb +23 -0
- data/profile/df_to_a.rb +10 -0
- data/profile/filter.rb +13 -0
- data/profile/joining.rb +13 -0
- data/profile/sorting.rb +12 -0
- data/profile/vector_each_with_index.rb +9 -0
- data/spec/accessors/wrappers_spec.rb +2 -4
- data/spec/categorical_spec.rb +1734 -0
- data/spec/core/group_by_spec.rb +52 -2
- data/spec/core/merge_spec.rb +63 -2
- data/spec/core/query_spec.rb +236 -80
- data/spec/dataframe_spec.rb +1373 -79
- data/spec/date_time/data_spec.rb +3 -5
- data/spec/date_time/index_spec.rb +154 -17
- data/spec/date_time/offsets_spec.rb +3 -4
- data/spec/fixtures/empties.dat +2 -0
- data/spec/fixtures/strings.dat +2 -0
- data/spec/formatters/table_formatter_spec.rb +99 -0
- data/spec/helpers_spec.rb +8 -0
- data/spec/index/categorical_index_spec.rb +168 -0
- data/spec/index/index_spec.rb +283 -0
- data/spec/index/multi_index_spec.rb +570 -0
- data/spec/io/io_spec.rb +31 -4
- data/spec/io/sql_data_source_spec.rb +0 -1
- data/spec/iruby/dataframe_spec.rb +172 -0
- data/spec/iruby/helpers_spec.rb +49 -0
- data/spec/iruby/multi_index_spec.rb +37 -0
- data/spec/iruby/vector_spec.rb +107 -0
- data/spec/math/arithmetic/dataframe_spec.rb +71 -13
- data/spec/math/arithmetic/vector_spec.rb +8 -10
- data/spec/math/statistics/dataframe_spec.rb +3 -5
- data/spec/math/statistics/vector_spec.rb +45 -55
- data/spec/monkeys_spec.rb +32 -9
- data/spec/plotting/dataframe_spec.rb +386 -0
- data/spec/plotting/vector_spec.rb +230 -0
- data/spec/shared/vector_display_spec.rb +215 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/vector_spec.rb +905 -138
- metadata +143 -11
- data/.rubocop_todo.yml +0 -44
- data/lib/daru/plotting/dataframe.rb +0 -104
- data/lib/daru/plotting/vector.rb +0 -38
- data/spec/daru_spec.rb +0 -58
- data/spec/index_spec.rb +0 -375
data/lib/daru/monkeys.rb
CHANGED
@@ -1,28 +1,4 @@
|
|
1
1
|
class Array
|
2
|
-
# Recode repeated values on an array, adding the number of repetition
|
3
|
-
# at the end
|
4
|
-
# Example:
|
5
|
-
# a=%w{a b c c d d d e}
|
6
|
-
# a.recode_repeated
|
7
|
-
# => ["a","b","c_1","c_2","d_1","d_2","d_3","e"]
|
8
|
-
def recode_repeated
|
9
|
-
return self if size == uniq.size
|
10
|
-
|
11
|
-
duplicated = group_by { |n| n }
|
12
|
-
.select { |_, g| g.size > 1 }.map(&:first)
|
13
|
-
|
14
|
-
counter = duplicated.collect { |n| [n, 0] }.to_h
|
15
|
-
|
16
|
-
collect do |n|
|
17
|
-
if counter.key?(n)
|
18
|
-
counter[n] += 1
|
19
|
-
'%s_%d' % [n, counter[n]]
|
20
|
-
else
|
21
|
-
n
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
2
|
def daru_vector name=nil, index=nil, dtype=:array
|
27
3
|
Daru::Vector.new self, name: name, index: index, dtype: dtype
|
28
4
|
end
|
@@ -54,6 +30,7 @@ class Hash
|
|
54
30
|
alias_method :dv, :daru_vector
|
55
31
|
end
|
56
32
|
|
33
|
+
# :nocov:
|
57
34
|
class NMatrix
|
58
35
|
def daru_vector(name=nil, index=nil, *)
|
59
36
|
Daru::Vector.new self, name: name, index: index, dtype: :nmatrix
|
@@ -70,12 +47,6 @@ class MDArray
|
|
70
47
|
alias_method :dv, :daru_vector
|
71
48
|
end
|
72
49
|
|
73
|
-
class Numeric
|
74
|
-
def square
|
75
|
-
self * self
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
50
|
class Matrix
|
80
51
|
def elementwise_division other
|
81
52
|
map.with_index do |e, index|
|
@@ -84,17 +55,18 @@ class Matrix
|
|
84
55
|
end
|
85
56
|
end
|
86
57
|
|
87
|
-
class
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
else
|
92
|
-
false
|
58
|
+
class Object
|
59
|
+
if RUBY_VERSION < '2.2'
|
60
|
+
def itself
|
61
|
+
self
|
93
62
|
end
|
94
63
|
end
|
95
64
|
end
|
96
65
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
66
|
+
module Daru
|
67
|
+
class DataFrame
|
68
|
+
# NOTE: This alias will soon be removed. Use to_h in all future work.
|
69
|
+
alias :to_hash :to_h
|
70
|
+
end
|
71
|
+
end
|
72
|
+
# :nocov:
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Daru
|
2
|
+
module Plotting
|
3
|
+
module Category
|
4
|
+
module GruffLibrary
|
5
|
+
def plot opts={}
|
6
|
+
type = opts[:type] || :bar
|
7
|
+
size = opts[:size] || 500
|
8
|
+
case type
|
9
|
+
when :bar, :pie, :sidebar
|
10
|
+
plot = send("category_#{type}_plot".to_sym, size, opts[:method])
|
11
|
+
else
|
12
|
+
raise ArgumentError, 'This type of plot is not supported.'
|
13
|
+
end
|
14
|
+
yield plot if block_given?
|
15
|
+
plot
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def category_bar_plot size, method
|
21
|
+
plot = Gruff::Bar.new size
|
22
|
+
method ||= :count
|
23
|
+
dv = frequencies(method)
|
24
|
+
plot.labels = size.times.to_a.zip(dv.index.to_a).to_h
|
25
|
+
plot.data name || :vector, dv.to_a
|
26
|
+
plot
|
27
|
+
end
|
28
|
+
|
29
|
+
def category_pie_plot size, method
|
30
|
+
plot = Gruff::Pie.new size
|
31
|
+
method ||= :count
|
32
|
+
frequencies(method).each_with_index do |data, index|
|
33
|
+
plot.data index, data
|
34
|
+
end
|
35
|
+
plot
|
36
|
+
end
|
37
|
+
|
38
|
+
def category_sidebar_plot size, method
|
39
|
+
plot = Gruff::SideBar.new size
|
40
|
+
plot.labels = {0 => (name.to_s || 'vector')}
|
41
|
+
frequencies(method).each_with_index do |data, index|
|
42
|
+
plot.data index, data
|
43
|
+
end
|
44
|
+
plot
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Daru
|
2
|
+
module Plotting
|
3
|
+
module DataFrame
|
4
|
+
module GruffLibrary
|
5
|
+
def plot opts={}
|
6
|
+
type = opts[:type] || :bar
|
7
|
+
size = opts[:size] || 500
|
8
|
+
x = extract_x_vector opts[:x]
|
9
|
+
y = extract_y_vectors opts[:y]
|
10
|
+
return plot_with_category(
|
11
|
+
size, type, x, y, opts[:categorized]
|
12
|
+
) if opts[:categorized]
|
13
|
+
case type
|
14
|
+
when :line, :bar, :scatter
|
15
|
+
plot = send("#{type}_plot", size, x, y)
|
16
|
+
# TODO: hist, box
|
17
|
+
# It turns out hist and box are not supported in Gruff yet
|
18
|
+
else
|
19
|
+
raise ArgumentError, 'This type of plot is not supported.'
|
20
|
+
end
|
21
|
+
yield plot if block_given?
|
22
|
+
plot
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def line_plot size, x, y
|
28
|
+
plot = Gruff::Line.new size
|
29
|
+
plot.labels = size.times.to_a.zip(x).to_h
|
30
|
+
y.each do |vec|
|
31
|
+
plot.data vec.name || :vector, vec.to_a
|
32
|
+
end
|
33
|
+
plot
|
34
|
+
end
|
35
|
+
|
36
|
+
def bar_plot size, x, y
|
37
|
+
plot = Gruff::Bar.new size
|
38
|
+
plot.labels = size.times.to_a.zip(x).to_h
|
39
|
+
y.each do |vec|
|
40
|
+
plot.data vec.name || :vector, vec.to_a
|
41
|
+
end
|
42
|
+
plot
|
43
|
+
end
|
44
|
+
|
45
|
+
def scatter_plot size, x, y
|
46
|
+
plot = Gruff::Scatter.new size
|
47
|
+
y.each do |vec|
|
48
|
+
plot.data vec.name || :vector, x, vec.to_a
|
49
|
+
end
|
50
|
+
plot
|
51
|
+
end
|
52
|
+
|
53
|
+
def plot_with_category size, type, x, y, opts
|
54
|
+
x = Daru::Vector.new x
|
55
|
+
y = y.first
|
56
|
+
case type
|
57
|
+
when :scatter
|
58
|
+
plot = Gruff::Scatter.new size
|
59
|
+
cat_dv = self[opts[:by]]
|
60
|
+
cat_dv.categories.each do |cat|
|
61
|
+
bools = cat_dv.eq cat
|
62
|
+
plot.data cat, x.where(bools).to_a, y.where(bools).to_a
|
63
|
+
end
|
64
|
+
else
|
65
|
+
raise ArgumentError, "Type #{type} is not supported."
|
66
|
+
end
|
67
|
+
yield plot if block_given?
|
68
|
+
plot
|
69
|
+
end
|
70
|
+
|
71
|
+
def extract_x_vector x_name
|
72
|
+
x_name && self[x_name].to_a || index.to_a
|
73
|
+
end
|
74
|
+
|
75
|
+
def extract_y_vectors y_names
|
76
|
+
y_names =
|
77
|
+
case y_names
|
78
|
+
when nil
|
79
|
+
vectors.to_a
|
80
|
+
when Array
|
81
|
+
y_names
|
82
|
+
else
|
83
|
+
[y_names]
|
84
|
+
end
|
85
|
+
|
86
|
+
y_names.map { |y| self[y] }.select(&:numeric?)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Daru
|
2
|
+
module Plotting
|
3
|
+
module Vector
|
4
|
+
module GruffLibrary
|
5
|
+
def plot opts={}
|
6
|
+
type = opts[:type] || :bar
|
7
|
+
size = opts[:size] || 500
|
8
|
+
case type
|
9
|
+
when :line, :bar, :pie, :scatter, :sidebar
|
10
|
+
plot = send("#{type}_plot", size)
|
11
|
+
# TODO: hist, box
|
12
|
+
# It turns out hist and box are not supported in Gruff yet
|
13
|
+
else
|
14
|
+
raise ArgumentError, 'This type of plot is not supported.'
|
15
|
+
end
|
16
|
+
yield plot if block_given?
|
17
|
+
plot
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def line_plot size
|
23
|
+
plot = Gruff::Line.new size
|
24
|
+
plot.labels = size.times.to_a.zip(index.to_a).to_h
|
25
|
+
plot.data name || :vector, to_a
|
26
|
+
plot
|
27
|
+
end
|
28
|
+
|
29
|
+
def bar_plot size
|
30
|
+
plot = Gruff::Bar.new size
|
31
|
+
plot.labels = size.times.to_a.zip(index.to_a).to_h
|
32
|
+
plot.data name || :vector, to_a
|
33
|
+
plot
|
34
|
+
end
|
35
|
+
|
36
|
+
def pie_plot size
|
37
|
+
plot = Gruff::Pie.new size
|
38
|
+
each_with_index { |data, index| plot.data index, data }
|
39
|
+
plot
|
40
|
+
end
|
41
|
+
|
42
|
+
def scatter_plot size
|
43
|
+
plot = Gruff::Scatter.new size
|
44
|
+
plot.data name || :vector, index.to_a, to_a
|
45
|
+
plot
|
46
|
+
end
|
47
|
+
|
48
|
+
def sidebar_plot size
|
49
|
+
plot = Gruff::SideBar.new size
|
50
|
+
plot.labels = {0 => (name.to_s || 'vector')}
|
51
|
+
each_with_index { |data, index| plot.data index, data }
|
52
|
+
plot
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Daru
|
2
|
+
module Plotting
|
3
|
+
module Category
|
4
|
+
module NyaplotLibrary
|
5
|
+
def plot opts
|
6
|
+
case type = opts[:type]
|
7
|
+
when :bar
|
8
|
+
plot = Nyaplot::Plot.new
|
9
|
+
opts[:method] ||= :count
|
10
|
+
values = frequencies opts[:method]
|
11
|
+
diagram = plot.add :bar, values.index.to_a, values.to_a
|
12
|
+
# Set yrange for good view
|
13
|
+
set_yrange plot, opts[:method]
|
14
|
+
yield plot, diagram if block_given?
|
15
|
+
plot.show
|
16
|
+
else
|
17
|
+
raise ArgumentError, "#{type} type is not supported."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def set_yrange plot, method
|
24
|
+
case method
|
25
|
+
when :percentage
|
26
|
+
plot.yrange [0, 100]
|
27
|
+
when :fraction
|
28
|
+
plot.yrange [0, 1]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
module Daru
|
2
|
+
module Plotting
|
3
|
+
module DataFrame
|
4
|
+
module NyaplotLibrary
|
5
|
+
# Plots a DataFrame with Nyaplot on IRuby using the given options. Yields
|
6
|
+
# the corresponding Nyaplot::Plot object and the Nyaplot::Diagram object
|
7
|
+
# to the block, if it is specified. See the nyaplot docs for info on how to
|
8
|
+
# further use these objects.
|
9
|
+
#
|
10
|
+
# Detailed instructions on use of the plotting API can be found in the
|
11
|
+
# notebooks whose links you can find in the README.
|
12
|
+
#
|
13
|
+
# == Options
|
14
|
+
#
|
15
|
+
# * +:type+ - Type of plot. Can be :scatter, :bar, :histogram, :line or :box.
|
16
|
+
# * +:x+ - Vector to be used for X co-ordinates.
|
17
|
+
# * +:y+ - Vector to be used for Y co-ordinates.
|
18
|
+
#
|
19
|
+
# == Usage
|
20
|
+
# # Simple bar chart
|
21
|
+
# df = Daru::DataFrame.new({a:['A', 'B', 'C', 'D', 'E'], b:[10,20,30,40,50]})
|
22
|
+
# df.plot type: :bar, x: :a, y: :b
|
23
|
+
def plot opts={}, &block
|
24
|
+
if opts[:categorized]
|
25
|
+
plot_with_category(opts, &block)
|
26
|
+
else
|
27
|
+
plot_without_category(opts, &block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def plot_without_category opts
|
34
|
+
options = {type: :scatter}.merge(opts)
|
35
|
+
|
36
|
+
plot = Nyaplot::Plot.new
|
37
|
+
types = extract_option :type, options
|
38
|
+
|
39
|
+
diagram =
|
40
|
+
case
|
41
|
+
when !([:scatter, :bar, :line, :histogram] & types).empty?
|
42
|
+
plot_regular_diagrams plot, opts
|
43
|
+
when types.include?(:box)
|
44
|
+
plot_box_diagram plot
|
45
|
+
else
|
46
|
+
raise ArgumentError, "Unidentified plot types: #{types}"
|
47
|
+
end
|
48
|
+
|
49
|
+
yield(plot, diagram) if block_given?
|
50
|
+
|
51
|
+
plot.show
|
52
|
+
end
|
53
|
+
|
54
|
+
def plot_with_category opts
|
55
|
+
case type = opts[:type]
|
56
|
+
when :scatter, :line
|
57
|
+
plot = Nyaplot::Plot.new
|
58
|
+
category_opts = opts[:categorized]
|
59
|
+
type = opts[:type]
|
60
|
+
x, y = opts[:x], opts[:y]
|
61
|
+
cat_dv = self[category_opts[:by]]
|
62
|
+
|
63
|
+
diagrams = create_categorized_diagrams plot, cat_dv, x, y, type
|
64
|
+
|
65
|
+
apply_variant_to_diagrams diagrams, category_opts, type
|
66
|
+
|
67
|
+
plot.legend true
|
68
|
+
yield plot, *diagrams if block_given?
|
69
|
+
plot.show
|
70
|
+
|
71
|
+
else
|
72
|
+
raise ArgumentError, "Unsupported type #{type}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_categorized_diagrams plot, cat_dv, x, y, type
|
77
|
+
cat_dv.categories.map do |cat|
|
78
|
+
x_vec = self[x].where(cat_dv.eq cat)
|
79
|
+
y_vec = self[y].where(cat_dv.eq cat)
|
80
|
+
df = Daru::DataFrame.new [x_vec, y_vec], order: [x, y]
|
81
|
+
nyaplot_df = df.to_nyaplotdf
|
82
|
+
|
83
|
+
plot.add_with_df(nyaplot_df, type, x, y)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def apply_variant_to_diagrams diagrams, category_opts, type
|
88
|
+
method = category_opts[:method]
|
89
|
+
cat_dv = self[category_opts[:by]]
|
90
|
+
# If user has mentioned custom color, size, shape use them
|
91
|
+
variant =
|
92
|
+
if category_opts[method]
|
93
|
+
category_opts[method].cycle
|
94
|
+
else
|
95
|
+
send("get_#{method}".to_sym, type)
|
96
|
+
end
|
97
|
+
|
98
|
+
diagrams.zip(cat_dv.categories) do |d, cat|
|
99
|
+
d.title cat
|
100
|
+
d.send(method, variant.next)
|
101
|
+
d.tooltip_contents [cat]*cat_dv.count(cat) if type == :scatter
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
SHAPES = %w(circle triangle-up diamond square triangle-down cross).freeze
|
106
|
+
def get_shape type
|
107
|
+
validate_type type, :scatter
|
108
|
+
SHAPES.cycle
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_size type
|
112
|
+
validate_type type, :scatter
|
113
|
+
(50..550).step(100).cycle
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_color(*)
|
117
|
+
Nyaplot::Colors.qual.cycle
|
118
|
+
end
|
119
|
+
|
120
|
+
def get_stroke_width type
|
121
|
+
validate_type type, :line
|
122
|
+
(2..16).step(2).cycle
|
123
|
+
end
|
124
|
+
|
125
|
+
def validate_type type, *types
|
126
|
+
raise ArgumentError, "Invalid option for #{type} type" unless
|
127
|
+
types.include? type
|
128
|
+
end
|
129
|
+
|
130
|
+
def single_diagram? options
|
131
|
+
options[:x] && options[:x].is_a?(Symbol)
|
132
|
+
end
|
133
|
+
|
134
|
+
def plot_regular_diagrams plot, opts
|
135
|
+
if single_diagram? opts
|
136
|
+
add_single_diagram plot, opts
|
137
|
+
else
|
138
|
+
add_multiple_diagrams plot, opts
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def plot_box_diagram plot
|
143
|
+
numeric = only_numerics(clone: false).reject_values(*Daru::MISSING_VALUES)
|
144
|
+
plot.add_with_df(numeric.to_nyaplotdf, :box, *numeric.vectors.to_a)
|
145
|
+
end
|
146
|
+
|
147
|
+
def add_single_diagram plot, options
|
148
|
+
args = [
|
149
|
+
to_nyaplotdf,
|
150
|
+
options[:type],
|
151
|
+
options[:x]
|
152
|
+
]
|
153
|
+
|
154
|
+
args << options[:y] if options[:y]
|
155
|
+
|
156
|
+
plot.add_with_df(*args)
|
157
|
+
end
|
158
|
+
|
159
|
+
def add_multiple_diagrams plot, options
|
160
|
+
types = extract_option :type, options
|
161
|
+
x_vecs = extract_option :x, options
|
162
|
+
y_vecs = extract_option :y, options
|
163
|
+
|
164
|
+
nyaplot_df = to_nyaplotdf
|
165
|
+
total = x_vecs.size
|
166
|
+
types = types.size < total ? types*total : types
|
167
|
+
|
168
|
+
types.zip(x_vecs, y_vecs).map do |t, xv, yv|
|
169
|
+
plot.add_with_df(nyaplot_df, t, xv, yv)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def extract_option opt, options
|
174
|
+
if options[opt]
|
175
|
+
o = options[opt]
|
176
|
+
o.is_a?(Array) ? o : [o]
|
177
|
+
else
|
178
|
+
options.keys
|
179
|
+
.select { |a| a =~ Regexp.new("\\A#{opt}") }
|
180
|
+
.sort
|
181
|
+
.map { |a| options[a] }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|