charty 0.1.5.dev → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,55 @@
1
+ module Charty
2
+ module TableAdapters
3
+ class ActiveRecordAdapter
4
+ TableAdapters.register(:active_record, self)
5
+
6
+ include Enumerable
7
+
8
+ def self.supported?(data)
9
+ defined?(ActiveRecord::Relation) && data.is_a?(ActiveRecord::Relation)
10
+ end
11
+
12
+ def initialize(data)
13
+ @data = check_type(ActiveRecord::Relation, data, :data)
14
+ @column_names = @data.column_names.freeze
15
+ @columns = nil
16
+ end
17
+
18
+ attr_reader :column_names
19
+
20
+ def [](row, column)
21
+ fetch_records unless @columns
22
+ if row
23
+ @columns[resolve_column_index(column)][row]
24
+ else
25
+ @columns[resolve_column_index(column)]
26
+ end
27
+ end
28
+
29
+ private def resolve_column_index(column)
30
+ case column
31
+ when String, Symbol
32
+ index = column_names.index(column.to_s)
33
+ unless index
34
+ raise IndexError, "invalid column name: #{column.inspect}"
35
+ end
36
+ index
37
+ when Integer
38
+ column
39
+ else
40
+ message = "column must be String or Integer: #{column.inspect}"
41
+ raise ArgumentError, message
42
+ end
43
+ end
44
+
45
+ private def fetch_records
46
+ @columns = @data.pluck(*column_names).transpose
47
+ end
48
+
49
+ private def check_type(type, data, name)
50
+ return data if data.is_a?(type)
51
+ raise TypeError, "#{name} must be a #{type}"
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ module Charty
2
+ module TableAdapters
3
+ class DaruAdapter
4
+ TableAdapters.register(:daru, self)
5
+
6
+ include Enumerable
7
+
8
+ def self.supported?(data)
9
+ defined?(Daru::DataFrame) && data.is_a?(Daru::DataFrame)
10
+ end
11
+
12
+ def initialize(data)
13
+ @data = check_type(Daru::DataFrame, data, :data)
14
+ end
15
+
16
+ def column_names
17
+ @data.vectors.to_a
18
+ end
19
+
20
+ def [](row, column)
21
+ if row
22
+ @data[column][row]
23
+ else
24
+ @data[column]
25
+ end
26
+ end
27
+
28
+ private def check_type(type, data, name)
29
+ return data if data.is_a?(type)
30
+ raise TypeError, "#{name} must be a #{type}"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ module Charty
2
+ module TableAdapters
3
+ class DatasetsAdapter
4
+ TableAdapters.register(:datasets, self)
5
+
6
+ include Enumerable
7
+
8
+ def self.supported?(data)
9
+ defined?(Datasets::Dataset) &&
10
+ data.is_a?(Datasets::Dataset)
11
+ end
12
+
13
+ def initialize(dataset)
14
+ @table = dataset.to_table
15
+ @records = []
16
+ end
17
+
18
+ def column_names
19
+ @table.column_names
20
+ end
21
+
22
+ def each(&block)
23
+ return to_enum(__method__) unless block_given?
24
+
25
+ @table.each_record(&block)
26
+ end
27
+
28
+ # @param [Integer] row Row index
29
+ # @param [Symbol,String,Integer] column Column index
30
+ def [](row, column)
31
+ if row
32
+ record = @table.find_record(row)
33
+ return nil if record.nil?
34
+ record[column]
35
+ else
36
+ @table[column]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,108 @@
1
+ require 'date'
2
+ require 'forwardable'
3
+
4
+ module Charty
5
+ module TableAdapters
6
+ class HashAdapter
7
+ TableAdapters.register(:hash, self)
8
+
9
+ extend Forwardable
10
+ include Enumerable
11
+
12
+ def self.supported?(data)
13
+ case data
14
+ when []
15
+ true
16
+ when Array
17
+ case data[0]
18
+ when Numeric, String, Time, Date
19
+ true
20
+ when Hash
21
+ data.all? {|el| el.is_a? Hash }
22
+ when method(:array?)
23
+ data.all?(&method(:array?))
24
+ end
25
+ when Hash
26
+ true
27
+ end
28
+ end
29
+
30
+ def self.array?(data)
31
+ case data
32
+ when Array,
33
+ ->(x) { defined?(Numo::NArray) && x.is_a?(Numo::NArray) },
34
+ ->(x) { defined?(Daru::Vector) && x.is_a?(Daru::Vector) },
35
+ ->(x) { defined?(NMatrix) && x.is_a?(NMatrix) }
36
+ true
37
+ else
38
+ false
39
+ end
40
+ end
41
+
42
+ def initialize(data, columns: nil)
43
+ case data
44
+ when Hash
45
+ @data = data
46
+ when Array
47
+ case data[0]
48
+ when Numeric, String, Time, Date
49
+ data = data.map {|x| [x] }
50
+ @data = make_data_from_records(data, columns)
51
+ when Hash
52
+ # TODO
53
+ when self.class.method(:array?)
54
+ unsupported_data_format unless data.all?(&self.class.method(:array?))
55
+ @data = make_data_from_records(data, columns)
56
+ else
57
+ unsupported_data_format
58
+ end
59
+ else
60
+ unsupported_data_format
61
+ end
62
+ end
63
+
64
+ def_delegator :@data, :keys, :column_names
65
+
66
+ def [](row, column)
67
+ if row
68
+ @data[column][row]
69
+ else
70
+ @data[column]
71
+ end
72
+ end
73
+
74
+ def each
75
+ i, n = 0, shape[0]
76
+ while i < n
77
+ record = @data.map {|k, v| v[i] }
78
+ yield record
79
+ i += 1
80
+ end
81
+ end
82
+
83
+ private def make_data_from_records(data, columns)
84
+ n_rows = data.length
85
+ n_columns = data.map(&:size).max
86
+ columns = generate_column_names(n_columns, columns)
87
+ columns.map.with_index { |key, j|
88
+ values = n_rows.times.map {|i| data[i][j] }
89
+ [key, values]
90
+ }.to_h
91
+ end
92
+
93
+ private def generate_column_names(n_columns, columns)
94
+ # FIXME: this is the same as NArrayAdapter#generate_column_names
95
+ columns ||= []
96
+ if columns.length >= n_columns
97
+ columns[0, n_columns]
98
+ else
99
+ columns + columns.length.upto(n_columns - 1).map {|i| "X#{i}" }
100
+ end
101
+ end
102
+
103
+ private def unsupported_data_format
104
+ raise ArgumentError, "Unsupported data format"
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,57 @@
1
+ module Charty
2
+ module TableAdapters
3
+ class NArrayAdapter
4
+ TableAdapters.register(:narray, self)
5
+
6
+ def self.supported?(data)
7
+ defined?(Numo::NArray) && data.is_a?(Numo::NArray) && data.ndim <= 2
8
+ end
9
+
10
+ def initialize(data, columns: nil)
11
+ case data.ndim
12
+ when 1
13
+ data = data.reshape(data.length, 1)
14
+ when 2
15
+ # do nothing
16
+ else
17
+ raise ArgumentError, "Unsupported data format"
18
+ end
19
+ @data = data
20
+ @column_names = generate_column_names(data.shape[1], columns)
21
+ end
22
+
23
+ attr_reader :column_names
24
+
25
+ def [](row, column)
26
+ if row
27
+ @data[row, resolve_column_index(column)]
28
+ else
29
+ @data[true, resolve_column_index(column)]
30
+ end
31
+ end
32
+
33
+ private def resolve_column_index(column)
34
+ case column
35
+ when String, Symbol
36
+ index = column_names.index(column.to_s)
37
+ return index if index
38
+ raise IndexError, "invalid column name: #{column}"
39
+ when Integer
40
+ column
41
+ else
42
+ message = "column must be String or Integer: #{column.inspect}"
43
+ raise ArgumentError, message
44
+ end
45
+ end
46
+
47
+ private def generate_column_names(n_columns, columns)
48
+ columns ||= []
49
+ if columns.length >= n_columns
50
+ columns[0, n_columns]
51
+ else
52
+ columns + columns.length.upto(n_columns - 1).map {|i| "X#{i}" }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,57 @@
1
+ module Charty
2
+ module TableAdapters
3
+ class NMatrixAdapter
4
+ TableAdapters.register(:nmatrix, self)
5
+
6
+ def self.supported?(data)
7
+ defined?(NMatrix) && data.is_a?(NMatrix) && data.shape.length <= 2
8
+ end
9
+
10
+ def initialize(data, columns: nil)
11
+ case data.shape.length
12
+ when 1
13
+ data = data.reshape(data.size, 1)
14
+ when 2
15
+ # do nothing
16
+ else
17
+ raise ArgumentError, "Unsupported data format"
18
+ end
19
+ @data = data
20
+ @column_names = generate_column_names(data.shape[1], columns)
21
+ end
22
+
23
+ attr_reader :column_names
24
+
25
+ def [](row, column)
26
+ if row
27
+ @data[row, resolve_column_index(column)]
28
+ else
29
+ @data[:*, resolve_column_index(column)].reshape([@data.shape[0]])
30
+ end
31
+ end
32
+
33
+ private def resolve_column_index(column)
34
+ case column
35
+ when String, Symbol
36
+ index = column_names.index(column.to_s)
37
+ return index if index
38
+ raise IndexError, "invalid column name: #{column}"
39
+ when Integer
40
+ column
41
+ else
42
+ message = "column must be String or Integer: #{column.inspect}"
43
+ raise ArgumentError, message
44
+ end
45
+ end
46
+
47
+ private def generate_column_names(n_columns, columns)
48
+ columns ||= []
49
+ if columns.length >= n_columns
50
+ columns[0, n_columns]
51
+ else
52
+ columns + columns.length.upto(n_columns - 1).map {|i| "X#{i}" }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,5 +1,5 @@
1
1
  module Charty
2
- VERSION = "0.1.5-dev"
2
+ VERSION = "0.2.0"
3
3
 
4
4
  module Version
5
5
  numbers, TAG = VERSION.split("-")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: charty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5.dev
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - youchan
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2019-07-09 00:00:00.000000000 Z
13
+ date: 2019-09-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -54,6 +54,90 @@ dependencies:
54
54
  - - ">="
55
55
  - !ruby/object:Gem::Version
56
56
  version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: numo-narray
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: nmatrix
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: red-datasets
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: 0.0.9
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 0.0.9
99
+ - !ruby/object:Gem::Dependency
100
+ name: daru
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ - !ruby/object:Gem::Dependency
114
+ name: activerecord
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: sqlite3
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
57
141
  - !ruby/object:Gem::Dependency
58
142
  name: matplotlib
59
143
  requirement: !ruby/object:Gem::Requirement
@@ -94,23 +178,30 @@ files:
94
178
  - examples/iris_dataset.ipynb
95
179
  - examples/nmatrix.ipynb
96
180
  - examples/numo-narray.ipynb
181
+ - examples/sample_bokeh.ipynb
97
182
  - examples/sample_google_chart.ipynb
98
183
  - examples/sample_gruff.ipynb
184
+ - examples/sample_images/bar_bokeh.html
99
185
  - examples/sample_images/bar_gruff.png
100
186
  - examples/sample_images/bar_pyplot.png
101
187
  - examples/sample_images/bar_rubyplot.png
188
+ - examples/sample_images/barh_bokeh.html
102
189
  - examples/sample_images/barh_gruff.png
103
190
  - examples/sample_images/barh_pyplot.png
191
+ - examples/sample_images/box_plot_bokeh.html
104
192
  - examples/sample_images/box_plot_pyplot.png
105
193
  - examples/sample_images/bubble_pyplot.png
106
194
  - examples/sample_images/bubble_rubyplot.png
195
+ - examples/sample_images/curve_bokeh.html
107
196
  - examples/sample_images/curve_gruff.png
108
197
  - examples/sample_images/curve_pyplot.png
109
198
  - examples/sample_images/curve_rubyplot.png
199
+ - examples/sample_images/curve_with_function_bokeh.html
110
200
  - examples/sample_images/curve_with_function_pyplot.png
111
201
  - examples/sample_images/curve_with_function_rubyplot.png
112
202
  - examples/sample_images/error_bar_pyplot.png
113
203
  - examples/sample_images/hist_pyplot.png
204
+ - examples/sample_images/scatter_bokeh.html
114
205
  - examples/sample_images/scatter_gruff.png
115
206
  - examples/sample_images/scatter_pyplot.png
116
207
  - examples/sample_images/scatter_rubyplot.png
@@ -120,16 +211,24 @@ files:
120
211
  - examples/sample_rubyplot.ipynb
121
212
  - images/design_concept.png
122
213
  - lib/charty.rb
214
+ - lib/charty/backends.rb
123
215
  - lib/charty/backends/bokeh.rb
124
216
  - lib/charty/backends/google_chart.rb
125
217
  - lib/charty/backends/gruff.rb
218
+ - lib/charty/backends/plotly.rb
126
219
  - lib/charty/backends/pyplot.rb
127
220
  - lib/charty/backends/rubyplot.rb
128
221
  - lib/charty/layout.rb
129
222
  - lib/charty/linspace.rb
130
223
  - lib/charty/plotter.rb
131
- - lib/charty/plotter_adapter.rb
132
224
  - lib/charty/table.rb
225
+ - lib/charty/table_adapters.rb
226
+ - lib/charty/table_adapters/active_record_adapter.rb
227
+ - lib/charty/table_adapters/daru_adapter.rb
228
+ - lib/charty/table_adapters/datasets_adapter.rb
229
+ - lib/charty/table_adapters/hash_adapter.rb
230
+ - lib/charty/table_adapters/narray_adapter.rb
231
+ - lib/charty/table_adapters/nmatrix_adapter.rb
133
232
  - lib/charty/version.rb
134
233
  homepage: https://github.com/red-data-tools/charty
135
234
  licenses:
@@ -146,9 +245,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
245
  version: '0'
147
246
  required_rubygems_version: !ruby/object:Gem::Requirement
148
247
  requirements:
149
- - - ">"
248
+ - - ">="
150
249
  - !ruby/object:Gem::Version
151
- version: 1.3.1
250
+ version: '0'
152
251
  requirements: []
153
252
  rubygems_version: 3.0.3
154
253
  signing_key: