charty 0.1.5.dev → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +71 -0
- data/.github/workflows/nmatrix.yml +67 -0
- data/.github/workflows/pycall.yml +86 -0
- data/Dockerfile.dev +9 -1
- data/Gemfile +18 -0
- data/README.md +176 -9
- data/Rakefile +4 -5
- data/charty.gemspec +10 -1
- data/examples/Gemfile +1 -0
- data/examples/active_record.ipynb +1 -1
- data/examples/daru.ipynb +1 -1
- data/examples/iris_dataset.ipynb +1 -1
- data/examples/nmatrix.ipynb +1 -1
- data/examples/{numo-narray.ipynb → numo_narray.ipynb} +1 -1
- data/examples/palette.rb +71 -0
- data/examples/sample.png +0 -0
- data/examples/sample_bokeh.ipynb +156 -0
- data/examples/sample_google_chart.ipynb +229 -68
- data/examples/sample_images/bar_bokeh.html +85 -0
- data/examples/sample_images/barh_bokeh.html +85 -0
- data/examples/sample_images/box_plot_bokeh.html +85 -0
- data/examples/sample_images/curve_bokeh.html +85 -0
- data/examples/sample_images/curve_with_function_bokeh.html +85 -0
- data/examples/sample_images/hist_gruff.png +0 -0
- data/examples/sample_images/scatter_bokeh.html +85 -0
- data/examples/sample_pyplot.ipynb +40 -38
- data/images/penguins_body_mass_g_flipper_length_mm_scatter_plot.png +0 -0
- data/images/penguins_body_mass_g_flipper_length_mm_species_scatter_plot.png +0 -0
- data/images/penguins_body_mass_g_flipper_length_mm_species_sex_scatter_plot.png +0 -0
- data/images/penguins_species_body_mass_g_bar_plot_h.png +0 -0
- data/images/penguins_species_body_mass_g_bar_plot_v.png +0 -0
- data/images/penguins_species_body_mass_g_box_plot_h.png +0 -0
- data/images/penguins_species_body_mass_g_box_plot_v.png +0 -0
- data/images/penguins_species_body_mass_g_sex_bar_plot_v.png +0 -0
- data/images/penguins_species_body_mass_g_sex_box_plot_v.png +0 -0
- data/lib/charty.rb +14 -1
- data/lib/charty/backend_methods.rb +8 -0
- data/lib/charty/backends.rb +80 -0
- data/lib/charty/backends/bokeh.rb +32 -26
- data/lib/charty/backends/google_charts.rb +267 -0
- data/lib/charty/backends/gruff.rb +102 -83
- data/lib/charty/backends/plotly.rb +685 -0
- data/lib/charty/backends/pyplot.rb +586 -92
- data/lib/charty/backends/rubyplot.rb +82 -74
- data/lib/charty/backends/unicode_plot.rb +79 -0
- data/lib/charty/index.rb +213 -0
- data/lib/charty/linspace.rb +1 -1
- data/lib/charty/missing_value_support.rb +14 -0
- data/lib/charty/plot_methods.rb +184 -0
- data/lib/charty/plotter.rb +48 -40
- data/lib/charty/plotters.rb +11 -0
- data/lib/charty/plotters/abstract_plotter.rb +183 -0
- data/lib/charty/plotters/bar_plotter.rb +201 -0
- data/lib/charty/plotters/box_plotter.rb +79 -0
- data/lib/charty/plotters/categorical_plotter.rb +380 -0
- data/lib/charty/plotters/count_plotter.rb +7 -0
- data/lib/charty/plotters/estimation_support.rb +84 -0
- data/lib/charty/plotters/random_support.rb +25 -0
- data/lib/charty/plotters/relational_plotter.rb +518 -0
- data/lib/charty/plotters/scatter_plotter.rb +104 -0
- data/lib/charty/plotters/vector_plotter.rb +6 -0
- data/lib/charty/statistics.rb +114 -0
- data/lib/charty/table.rb +80 -3
- data/lib/charty/table_adapters.rb +25 -0
- data/lib/charty/table_adapters/active_record_adapter.rb +63 -0
- data/lib/charty/table_adapters/base_adapter.rb +69 -0
- data/lib/charty/table_adapters/daru_adapter.rb +70 -0
- data/lib/charty/table_adapters/datasets_adapter.rb +49 -0
- data/lib/charty/table_adapters/hash_adapter.rb +224 -0
- data/lib/charty/table_adapters/narray_adapter.rb +76 -0
- data/lib/charty/table_adapters/nmatrix_adapter.rb +67 -0
- data/lib/charty/table_adapters/pandas_adapter.rb +81 -0
- data/lib/charty/util.rb +20 -0
- data/lib/charty/vector.rb +69 -0
- data/lib/charty/vector_adapters.rb +183 -0
- data/lib/charty/vector_adapters/array_adapter.rb +109 -0
- data/lib/charty/vector_adapters/daru_adapter.rb +171 -0
- data/lib/charty/vector_adapters/narray_adapter.rb +187 -0
- data/lib/charty/vector_adapters/nmatrix_adapter.rb +37 -0
- data/lib/charty/vector_adapters/numpy_adapter.rb +168 -0
- data/lib/charty/vector_adapters/pandas_adapter.rb +200 -0
- data/lib/charty/version.rb +1 -1
- metadata +179 -10
- data/.travis.yml +0 -11
- data/lib/charty/backends/google_chart.rb +0 -167
- data/lib/charty/plotter_adapter.rb +0 -17
data/.travis.yml
DELETED
@@ -1,167 +0,0 @@
|
|
1
|
-
module Charty
|
2
|
-
class GoogleChart < PlotterAdapter
|
3
|
-
Name = "google_chart"
|
4
|
-
attr_reader :context
|
5
|
-
|
6
|
-
def self.chart_id=(chart_id)
|
7
|
-
@chart_id = chart_id
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.chart_id
|
11
|
-
@chart_id ||= 0
|
12
|
-
end
|
13
|
-
|
14
|
-
def initilize
|
15
|
-
end
|
16
|
-
|
17
|
-
def label(x, y)
|
18
|
-
end
|
19
|
-
|
20
|
-
def series=(series)
|
21
|
-
@series = series
|
22
|
-
end
|
23
|
-
|
24
|
-
def render(context, filename)
|
25
|
-
plot(nil, context)
|
26
|
-
end
|
27
|
-
|
28
|
-
def plot(plot, context)
|
29
|
-
@context = context
|
30
|
-
self.class.chart_id = self.class.chart_id + 1
|
31
|
-
|
32
|
-
case context.method
|
33
|
-
when :bar
|
34
|
-
generate_render_js("BarChart")
|
35
|
-
when :scatter
|
36
|
-
generate_render_js("ScatterChart")
|
37
|
-
when :bubble
|
38
|
-
generate_render_js("BubbleChart")
|
39
|
-
else
|
40
|
-
raise NotImplementedError
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def google_chart_load_tag
|
47
|
-
"<script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>"
|
48
|
-
end
|
49
|
-
|
50
|
-
def headers
|
51
|
-
[].tap do |header|
|
52
|
-
header << context.xlabel
|
53
|
-
context.series.to_a.each_with_index do |series_data, index|
|
54
|
-
header << series_data.label || index
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def x_labels
|
60
|
-
[].tap do |label|
|
61
|
-
context.series.each do |series|
|
62
|
-
series.xs.each do |xs_data|
|
63
|
-
label << xs_data unless label.any? { |label| label == xs_data }
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def data_hash
|
70
|
-
{}.tap do |hash|
|
71
|
-
context.series.to_a.each_with_index do |series_data, series_index|
|
72
|
-
x_labels.sort.each do |x_label|
|
73
|
-
unless hash[x_label]
|
74
|
-
hash[x_label] = []
|
75
|
-
end
|
76
|
-
|
77
|
-
if data_index = series_data.xs.to_a.index(x_label)
|
78
|
-
hash[x_label] << series_data.ys.to_a[data_index]
|
79
|
-
else
|
80
|
-
hash[x_label] << "null"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def formatted_data_array
|
88
|
-
case context.method
|
89
|
-
when :bubble
|
90
|
-
[["ID", "X", "Y", "GROUP", "SIZE"]].tap do |data_array|
|
91
|
-
context.series.to_a.each_with_index do |series_data, series_index|
|
92
|
-
series_data.xs.to_a.each_with_index do |data, data_index|
|
93
|
-
data_array << [
|
94
|
-
"",
|
95
|
-
series_data.xs.to_a[data_index] || "null",
|
96
|
-
series_data.ys.to_a[data_index] || "null",
|
97
|
-
series_data[:label] || series_index,
|
98
|
-
series_data.zs.to_a[data_index] || "null",
|
99
|
-
]
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
else
|
104
|
-
[headers.map(&:to_s)].tap do |data_array|
|
105
|
-
data_hash.each do |k, v|
|
106
|
-
data_array << [k.to_s, v].flatten
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def x_range_option
|
113
|
-
x_range = context&.range&.fetch(:x, nil)
|
114
|
-
{
|
115
|
-
max: x_range&.max,
|
116
|
-
min: x_range&.min,
|
117
|
-
}.reject { |_k, v| v.nil? }
|
118
|
-
end
|
119
|
-
|
120
|
-
def y_range_option
|
121
|
-
y_range = context&.range&.fetch(:y, nil)
|
122
|
-
{
|
123
|
-
max: y_range&.max,
|
124
|
-
min: y_range&.min,
|
125
|
-
}.reject { |_k, v| v.nil? }
|
126
|
-
end
|
127
|
-
|
128
|
-
def generate_render_js(chart_type)
|
129
|
-
js = <<-JS
|
130
|
-
#{google_chart_load_tag}
|
131
|
-
<script type="text/javascript">
|
132
|
-
google.charts.load("current", {packages:["corechart"]});
|
133
|
-
google.charts.setOnLoadCallback(drawChart);
|
134
|
-
function drawChart() {
|
135
|
-
const data = google.visualization.arrayToDataTable(
|
136
|
-
#{formatted_data_array}
|
137
|
-
);
|
138
|
-
|
139
|
-
const view = new google.visualization.DataView(data);
|
140
|
-
|
141
|
-
const options = {
|
142
|
-
title: "#{context.title}",
|
143
|
-
vAxis: {
|
144
|
-
title: "#{context.ylabel}",
|
145
|
-
viewWindow: {
|
146
|
-
max: #{y_range_option[:max] || "null"},
|
147
|
-
min: #{y_range_option[:min] || "null"},
|
148
|
-
},
|
149
|
-
},
|
150
|
-
hAxis: {
|
151
|
-
title: "#{context.xlabel}",
|
152
|
-
viewWindow: {
|
153
|
-
max: #{x_range_option[:max] || "null"},
|
154
|
-
min: #{x_range_option[:min] || "null"},
|
155
|
-
}
|
156
|
-
},
|
157
|
-
legend: { position: "none" },
|
158
|
-
};
|
159
|
-
const chart = new google.visualization.#{chart_type}(document.getElementById("#{chart_type}-#{self.class.chart_id}"));
|
160
|
-
chart.draw(view, options);
|
161
|
-
}
|
162
|
-
</script>
|
163
|
-
<div id="#{chart_type}-#{self.class.chart_id}" style="width: 900px; height: 300px;"></div>
|
164
|
-
JS
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Charty
|
2
|
-
class AdapterNotLoadedError < RuntimeError; end
|
3
|
-
|
4
|
-
class PlotterAdapter
|
5
|
-
def self.inherited(adapter_class)
|
6
|
-
@adapters ||= []
|
7
|
-
@adapters << adapter_class
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.create(adapter_name)
|
11
|
-
require "charty/backends/#{adapter_name}"
|
12
|
-
adapter = @adapters.find {|adapter| adapter::Name.to_s == adapter_name.to_s }
|
13
|
-
raise AdapterNotLoadedError.new("Adapter for '#{adapter_name}' is not found.") unless adapter
|
14
|
-
adapter.new
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|