charty 0.2.3 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +56 -23
  3. data/.github/workflows/nmatrix.yml +67 -0
  4. data/.github/workflows/pycall.yml +86 -0
  5. data/Gemfile +18 -0
  6. data/README.md +172 -4
  7. data/Rakefile +4 -5
  8. data/charty.gemspec +10 -6
  9. data/examples/sample_images/hist_gruff.png +0 -0
  10. data/images/penguins_body_mass_g_flipper_length_mm_scatter_plot.png +0 -0
  11. data/images/penguins_body_mass_g_flipper_length_mm_species_scatter_plot.png +0 -0
  12. data/images/penguins_body_mass_g_flipper_length_mm_species_sex_scatter_plot.png +0 -0
  13. data/images/penguins_species_body_mass_g_bar_plot_h.png +0 -0
  14. data/images/penguins_species_body_mass_g_bar_plot_v.png +0 -0
  15. data/images/penguins_species_body_mass_g_box_plot_h.png +0 -0
  16. data/images/penguins_species_body_mass_g_box_plot_v.png +0 -0
  17. data/images/penguins_species_body_mass_g_sex_bar_plot_v.png +0 -0
  18. data/images/penguins_species_body_mass_g_sex_box_plot_v.png +0 -0
  19. data/lib/charty.rb +8 -1
  20. data/lib/charty/backends/bokeh.rb +2 -2
  21. data/lib/charty/backends/google_charts.rb +1 -1
  22. data/lib/charty/backends/gruff.rb +14 -3
  23. data/lib/charty/backends/plotly.rb +731 -32
  24. data/lib/charty/backends/plotly_helpers/html_renderer.rb +203 -0
  25. data/lib/charty/backends/plotly_helpers/notebook_renderer.rb +87 -0
  26. data/lib/charty/backends/plotly_helpers/plotly_renderer.rb +121 -0
  27. data/lib/charty/backends/pyplot.rb +514 -66
  28. data/lib/charty/backends/rubyplot.rb +1 -1
  29. data/lib/charty/cache_dir.rb +27 -0
  30. data/lib/charty/dash_pattern_generator.rb +57 -0
  31. data/lib/charty/index.rb +213 -0
  32. data/lib/charty/iruby_helper.rb +18 -0
  33. data/lib/charty/linspace.rb +1 -1
  34. data/lib/charty/plot_methods.rb +283 -8
  35. data/lib/charty/plotter.rb +2 -2
  36. data/lib/charty/plotters.rb +11 -0
  37. data/lib/charty/plotters/abstract_plotter.rb +186 -16
  38. data/lib/charty/plotters/bar_plotter.rb +189 -7
  39. data/lib/charty/plotters/box_plotter.rb +64 -11
  40. data/lib/charty/plotters/categorical_plotter.rb +272 -40
  41. data/lib/charty/plotters/count_plotter.rb +7 -0
  42. data/lib/charty/plotters/distribution_plotter.rb +143 -0
  43. data/lib/charty/plotters/estimation_support.rb +84 -0
  44. data/lib/charty/plotters/histogram_plotter.rb +186 -0
  45. data/lib/charty/plotters/line_plotter.rb +300 -0
  46. data/lib/charty/plotters/random_support.rb +25 -0
  47. data/lib/charty/plotters/relational_plotter.rb +635 -0
  48. data/lib/charty/plotters/scatter_plotter.rb +80 -0
  49. data/lib/charty/plotters/vector_plotter.rb +6 -0
  50. data/lib/charty/statistics.rb +96 -2
  51. data/lib/charty/table.rb +160 -15
  52. data/lib/charty/table_adapters.rb +2 -0
  53. data/lib/charty/table_adapters/active_record_adapter.rb +17 -9
  54. data/lib/charty/table_adapters/base_adapter.rb +166 -0
  55. data/lib/charty/table_adapters/daru_adapter.rb +39 -3
  56. data/lib/charty/table_adapters/datasets_adapter.rb +13 -2
  57. data/lib/charty/table_adapters/hash_adapter.rb +141 -16
  58. data/lib/charty/table_adapters/narray_adapter.rb +25 -6
  59. data/lib/charty/table_adapters/nmatrix_adapter.rb +15 -5
  60. data/lib/charty/table_adapters/pandas_adapter.rb +163 -0
  61. data/lib/charty/util.rb +28 -0
  62. data/lib/charty/vector.rb +69 -0
  63. data/lib/charty/vector_adapters.rb +187 -0
  64. data/lib/charty/vector_adapters/array_adapter.rb +101 -0
  65. data/lib/charty/vector_adapters/daru_adapter.rb +163 -0
  66. data/lib/charty/vector_adapters/narray_adapter.rb +182 -0
  67. data/lib/charty/vector_adapters/nmatrix_adapter.rb +37 -0
  68. data/lib/charty/vector_adapters/numpy_adapter.rb +168 -0
  69. data/lib/charty/vector_adapters/pandas_adapter.rb +199 -0
  70. data/lib/charty/version.rb +1 -1
  71. metadata +92 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2b78866e47f947e7cad0c06c3f53418ff07fa6fccce7941b53eb63f70cb8db0
4
- data.tar.gz: 39c01144436ceee129c4d938ca8607b15c17292205f4f22da936442f89b2b2ca
3
+ metadata.gz: 0c245a8324486b73226c85162c602997c5b8e4f41c6fc03d731cd7c8c0e0c763
4
+ data.tar.gz: 720f08fdcf14ac5da11eace6f684d002c694de1d1b062fa9b954da4a286ae810
5
5
  SHA512:
6
- metadata.gz: 3e83c4308b434b0e3b43e7ed083eefe249b46c3333be00501adee2bd299d4a6e34a78fa2c913f77876cf4ba1448468b553256cd68e22e8a0fe90b5d85b6daaec
7
- data.tar.gz: e95895415c62bf352b6bdde4be7d04b7d12278a74a6e1e927376c99b2afc30a81c223e77c3f14848873d2f822233aa7557c4119471eba372af80d61db21756ba
6
+ metadata.gz: 253bf7b26d3ee72fe604afb4cdf50de412aa956171dc6671c33a158e2252597f71005fbbccb0f879f11688327339bf569f653f15eef6ac30faa4c0173765d607
7
+ data.tar.gz: b3cbfbd190a145c41db3d3fec8050f9ec4b9ddc12d978fb2c96a3a825409b708c8c0d6f14456ed0bf17f2c8150999ec063a1898d97b37c3e984a88645adc0d4b
@@ -1,38 +1,71 @@
1
1
  name: CI
2
2
 
3
3
  on:
4
- - push
5
- - pull_request
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ types:
9
+ - opened
10
+ - synchronize
11
+ - reopened
6
12
 
7
13
  jobs:
8
14
  test:
9
- name: Test
10
-
11
- runs-on: ubuntu-latest
15
+ name: ${{ matrix.os }}/${{ matrix.ruby }}
16
+ runs-on: ${{ matrix.os }}
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ os:
21
+ - ubuntu-20.04
22
+ - ubuntu-18.04
23
+ ruby:
24
+ - "3.0"
25
+ - 2.7
26
+ - 2.6
27
+ include:
28
+ - { os: ubuntu-20.04 , ruby: head }
12
29
 
13
30
  steps:
14
- - uses: actions/checkout@v1
31
+ - uses: actions/checkout@v2
32
+
33
+ - name: Set up Ruby
34
+ uses: ruby/setup-ruby@v1
35
+ with:
36
+ ruby-version: ${{ matrix.ruby }}
15
37
 
16
- - name: Set up Ruby 2.6
17
- uses: actions/setup-ruby@v1
38
+ - uses: actions/cache@v2
39
+ if: runner.os == 'Linux'
18
40
  with:
19
- ruby-version: 2.6.x
41
+ path: ~/.cache/red-datasets
42
+ key: ${{ runner.os }}-${{ hashFiles('lib/**') }}
43
+ restore-keys: ${{ runner.os }}-
20
44
 
21
- - name: Set up Python 3.7
22
- uses: actions/setup-python@v1
45
+ - uses: actions/cache@v2
46
+ if: |
47
+ runner.os == 'macOS'
23
48
  with:
24
- python-version: 3.7
49
+ path: |
50
+ ~/Library/Caches/red-datasets
51
+ key: ${{ runner.os }}-${{ hashFiles('lib/**') }}
52
+ restore-keys: ${{ runner.os }}-
53
+
54
+ - uses: actions/cache@v2
55
+ if: |
56
+ runner.os == 'Windows'
57
+ with:
58
+ path: |
59
+ ~/AppData/red-datasets
60
+ key: ${{ runner.os }}-${{ hashFiles('lib/**') }}
61
+ restore-keys: ${{ runner.os }}-
62
+
63
+ - run: sudo apt install build-essential libsqlite3-dev
64
+
65
+ - run: bundle install --jobs 4 --retry 3 --without "nmatrix python"
25
66
 
26
- - name: Install dependencies
27
- run: |
28
- sudo apt install build-essential libsqlite3-dev
67
+ - run: bundle exec rake
29
68
 
30
- - name: Install matplotlib
31
- run: |
32
- pip install --user matplotlib
69
+ - run: rake build
33
70
 
34
- - name: Build and test with Rake
35
- run: |
36
- gem install bundler
37
- bundle install --jobs 4 --retry 3
38
- bundle exec rake
71
+ - run: gem install --user pkg/*.gem
@@ -0,0 +1,67 @@
1
+ name: CI with NMatrix
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ types:
9
+ - opened
10
+ - synchronize
11
+ - reopened
12
+
13
+ jobs:
14
+ test:
15
+ name: ${{ matrix.os }}/${{ matrix.ruby }}
16
+ runs-on: ${{ matrix.os }}
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ os:
21
+ - ubuntu-20.04
22
+ ruby:
23
+ - 2.7
24
+ - 2.6
25
+
26
+ steps:
27
+ - uses: actions/checkout@v2
28
+
29
+ - name: Set up Ruby
30
+ uses: ruby/setup-ruby@v1
31
+ with:
32
+ ruby-version: ${{ matrix.ruby }}
33
+
34
+ - uses: actions/cache@v2
35
+ if: runner.os == 'Linux'
36
+ with:
37
+ path: ~/.cache/red-datasets
38
+ key: ${{ runner.os }}-${{ hashFiles('lib/**') }}
39
+ restore-keys: ${{ runner.os }}-
40
+
41
+ - uses: actions/cache@v2
42
+ if: |
43
+ runner.os == 'macOS'
44
+ with:
45
+ path: |
46
+ ~/Library/Caches/red-datasets
47
+ key: ${{ runner.os }}-${{ hashFiles('lib/**') }}
48
+ restore-keys: ${{ runner.os }}-
49
+
50
+ - uses: actions/cache@v2
51
+ if: |
52
+ runner.os == 'Windows'
53
+ with:
54
+ path: |
55
+ ~/AppData/red-datasets
56
+ key: ${{ runner.os }}-${{ hashFiles('lib/**') }}
57
+ restore-keys: ${{ runner.os }}-
58
+
59
+ - run: sudo apt install build-essential libsqlite3-dev
60
+
61
+ - run: bundle install --jobs 4 --retry 3 --without "numo python"
62
+
63
+ - run: bundle exec rake
64
+
65
+ - run: rake build
66
+
67
+ - run: gem install --user pkg/*.gem
@@ -0,0 +1,86 @@
1
+ name: CI with matplotlib and pandas
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ types:
9
+ - opened
10
+ - synchronize
11
+ - reopened
12
+
13
+ jobs:
14
+ test:
15
+ name: ${{ matrix.os }}/${{ matrix.ruby }}/${{ matrix.python }}-${{ matrix.python_architecture }}
16
+ runs-on: ${{ matrix.os }}
17
+
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ os:
22
+ - ubuntu-20.04
23
+ - ubuntu-18.04
24
+ ruby:
25
+ - "3.0"
26
+ - 2.7
27
+ - 2.6
28
+ python:
29
+ - 3.x
30
+ - 2.x
31
+ python_architecture:
32
+ - x64
33
+ include:
34
+ - { os: ubuntu-20.04 , ruby: head , python: 3.x , python_architecture: x64 }
35
+
36
+ steps:
37
+ - uses: actions/checkout@v2
38
+
39
+ - name: Setup Ruby
40
+ uses: ruby/setup-ruby@v1
41
+ with:
42
+ ruby-version: ${{ matrix.ruby }}
43
+
44
+ - name: Setup Python
45
+ uses: actions/setup-python@v2
46
+ with:
47
+ python-version: ${{ matrix.python }}
48
+ architecture: ${{ matrix.python_architecture }}
49
+
50
+ - uses: actions/cache@v2
51
+ if: runner.os == 'Linux'
52
+ with:
53
+ path: ~/.cache/red-datasets
54
+ key: ${{ runner.os }}-${{ hashFiles('lib/**') }}
55
+ restore-keys: ${{ runner.os }}-
56
+
57
+ - uses: actions/cache@v2
58
+ if: |
59
+ runner.os == 'macOS'
60
+ with:
61
+ path: |
62
+ ~/Library/Caches/red-datasets
63
+ key: ${{ runner.os }}-${{ hashFiles('lib/**') }}
64
+ restore-keys: ${{ runner.os }}-
65
+
66
+ - uses: actions/cache@v2
67
+ if: |
68
+ runner.os == 'Windows'
69
+ with:
70
+ path: |
71
+ ~/AppData/red-datasets
72
+ key: ${{ runner.os }}-${{ hashFiles('lib/**') }}
73
+ restore-keys: ${{ runner.os }}-
74
+
75
+ - run: sudo apt install build-essential libsqlite3-dev
76
+
77
+ - run: pip install --user matplotlib pandas
78
+
79
+ - run: bundle install --jobs 4 --retry 3 --without "nmatrix numo"
80
+
81
+ - run: python -V
82
+
83
+ - run: bundle exec rake
84
+ env:
85
+ PYTHON: python
86
+ continue-on-error: ${{ matrix.python == '2.x' }}
data/Gemfile CHANGED
@@ -4,3 +4,21 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in charty.gemspec
6
6
  gemspec
7
+
8
+ group :cruby do
9
+ gem "enumerable-statistics"
10
+ end
11
+
12
+ group :nmatrix do
13
+ gem "nmatrix"
14
+ end
15
+
16
+ group :numo do
17
+ gem "numo-narray"
18
+ end
19
+
20
+ group :python do
21
+ gem "matplotlib"
22
+ gem "numpy"
23
+ gem "pandas"
24
+ end
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # Charty - Visualizing your data in Ruby
2
2
 
3
- [![Build Status](https://travis-ci.org/red-data-tools/charty.svg?branch=master)](https://travis-ci.org/red-data-tools/charty)
3
+ ![Build Status](https://github.com/red-data-tools/charty/workflows/CI/badge.svg)
4
+ [![Gem Version](https://badge.fury.io/rb/charty.svg)](https://badge.fury.io/rb/charty)
4
5
  [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/red-data-tools/charty/master?filepath=iris_dataset.ipynb)
6
+ [![Docs](https://img.shields.io/badge/docs-stable-blue.svg)](https://rubydoc.info/gems/charty)
5
7
 
6
8
  Charty is open-source Ruby library for visualizing your data in a simple way.
7
9
  In Charty, you need to write very few lines of code for representing what you want to do.
@@ -32,8 +34,8 @@ $ CONFIGURE_OPTS="--enable-shared" pyenv install 3.x.x
32
34
  ### With Matplotlib
33
35
 
34
36
  ```
35
- sudo gem install charty --pre
36
- sudo gem install matplotlib
37
+ gem install charty --pre
38
+ gem install matplotlib
37
39
  sudo apt install python3-pip
38
40
  sudo python3 -m pip install -U pip matplotlib
39
41
  ```
@@ -55,6 +57,172 @@ $ docker run --rm -it -v $(pwd):/charty -p 8888:8888 charty-dev:latest
55
57
 
56
58
  ## Usage
57
59
 
60
+ ### Statistical plotting interface
61
+
62
+ Charty supports statistical plotting as Python's seaborn.
63
+
64
+ In the following examplles, we use the `penguins` dataset provided in red-datasets.
65
+
66
+ ```ruby
67
+ require "datasets"
68
+
69
+ penguins = Datasets::Penguins.new
70
+ ```
71
+
72
+ #### A basic workflow
73
+
74
+ The following code shows a basic workflow of the visualization with Charty.
75
+
76
+ First you need to load the Charty library.
77
+
78
+ ```ruby
79
+ require "charty"
80
+ ```
81
+
82
+ Next you msut have a dataset you want to visualize. Here, we use the penguins dataset provided in red-datasets library.
83
+
84
+ ```ruby
85
+ require "datasets"
86
+ penguins = Datasets::Penguins.new
87
+ ```
88
+
89
+ Next you need to create a plotter object by a plotting method. Here, we use `scatter_plot` method to show the relationship
90
+ among `body_mass_g`, `flipper_length_mm`, and `species` columns in the penguins dataset.
91
+
92
+ ```ruby
93
+ plot = Charty.scatter_plot(data: penguins, x: :body_mass_g, y: :flipper_length_mm, color: :species)
94
+ ```
95
+
96
+ If you want to render and save this plotter object into an HTML file by plotly backend, you can do it like below.
97
+
98
+ ```ruby
99
+ Charty::Backends.use(:plotly) # select plotly backend
100
+ plot.save("scatter.html") # save the plot as an HTML file
101
+ ```
102
+
103
+ When you already have prepared [playwright-ruby-client](https://github.com/YusukeIwaki/playwright-ruby-client),
104
+ you can render a plot into a PNG file by plotly backend by specifying a filename with `.png` extension.
105
+
106
+ ```ruby
107
+ plot.save("scatter.png")
108
+ ```
109
+
110
+ #### Jupyter Notebook
111
+
112
+ If you use Charty on Jupyter Notebook with IRuby kerenl (a.k.a. IRuby notebook),
113
+ you can render the plot just evaluate a plotter object. For example, the code below shows a scatter plot figure in
114
+ the output area.
115
+
116
+ ```ruby
117
+ Charty::Backends.use(:plotly)
118
+
119
+ Charty.scatter_plot(data: penguins, x: :body_mass_g, y: :flipper_length_mm, color: :species)
120
+ ```
121
+
122
+ Note that if you want to use the pyplot backend, you need to activate the integration between the pyplot backend and IRuby.
123
+ You can activate the integration by the following two lines.
124
+
125
+ ```ruby
126
+ Charty::Backends.use(:pyplot)
127
+ Charty::Backends::Pyplot.activate_iruby_integration
128
+ ```
129
+
130
+ #### Bar plot
131
+
132
+ Charty's statistical bar plot shows the relationship between a categorical variable and estimated means of a numeric variable.
133
+ This plot automatically calculates mean estimation and its 95% confidence interval of the numeric variable.
134
+
135
+ When we specify the categorical varaible as x-axis, the plot draws a vertical bar chart.
136
+ Instead, when we specify the categorical variable as y-axis, the plot draws a horizontal bar chart.
137
+
138
+ The following code shows the relationship between species and the mean body masses of penguins in a vertical bar chart.
139
+
140
+ ```ruby
141
+ Charty.bar_plot(data: penguins, x: :species, y: :body_mass_g)
142
+ ```
143
+
144
+ ![](images/penguins_species_body_mass_g_bar_plot_v.png)
145
+
146
+ Exchanging x and y axes alternates the orientation of the resulting chart.
147
+
148
+ ```ruby
149
+ Charty.bar_plot(data: penguins, x: :body_mass_g, y: :species)
150
+ ```
151
+
152
+ ![](images/penguins_species_body_mass_g_bar_plot_h.png)
153
+
154
+ Adding color axis introduces color grouping in the bar plot.
155
+
156
+ ```ruby
157
+ Charty.bar_plot(data: penguins, x: :species, y: :body_mass_g, color: :sex)
158
+ ```
159
+
160
+ ![](images/penguins_species_body_mass_g_sex_bar_plot_v.png)
161
+
162
+ #### Box plot
163
+
164
+ Charty's statistical box plot shows distributions of a numeric variable per categories.
165
+ The distributions are showed by boxes with whiskers that characterized by five-number summary.
166
+ This plot automatically calculates five-number summary the numeric variable per categories.
167
+
168
+ When we specify the categorical varaible as x-axis, the plot draws a vertical box plot chart.
169
+ Instead, when we specify the categorical variable as y-axis, the plot draws a horizontal box plot chart.
170
+
171
+ The following code draws a vertical box plot to show distributions of penguins' body mass per species.
172
+
173
+ ```ruby
174
+ Charty.box_plot(data: penguins, x: :species, y: :body_mass_g)
175
+ ```
176
+
177
+ ![](images/penguins_species_body_mass_g_box_plot_v.png)
178
+
179
+ As `bar_plot` above, exchanging x and y axes alternates the orientation of the resulting chart.
180
+
181
+ ```ruby
182
+ Charty.box_plot(data: penguins, x: :body_mass_g, y: :species)
183
+ ```
184
+
185
+ ![](images/penguins_species_body_mass_g_box_plot_h.png)
186
+
187
+ Adding color axis introduces color grouping in the box plot.
188
+
189
+ ```ruby
190
+ Charty.box_plot(data: penguins, x: :species, y: :body_mass_g, color: :sex)
191
+ ```
192
+
193
+ ![](images/penguins_species_body_mass_g_sex_box_plot_v.png)
194
+
195
+ #### Scatter plot
196
+
197
+ Charty's scatter plot shows the relationship between two numeric variables.
198
+
199
+ ```ruby
200
+ Charty.scatter_plot(data: penguins, x: :body_mass_g, y: flipper_length_mm)
201
+ ```
202
+
203
+ ![](images/penguins_body_mass_g_flipper_length_mm_scatter_plot.png)
204
+
205
+ Adding color axis introduces color grouping in the scatter plot.
206
+ The following example specifies `:species` variable in the color axis.
207
+ It shows the different species by the different colors.
208
+
209
+ ```ruby
210
+ Charty.scatter_plot(data: penguins, x: :body_mass_g, y: flipper_length_mm, color: :species)
211
+ ```
212
+
213
+ ![](images/penguins_body_mass_g_flipper_length_mm_species_scatter_plot.png)
214
+
215
+ Moreover, size and style axes can be specified.
216
+ The following example specifies `:sex` variable in the style axis.
217
+
218
+ ```ruby
219
+ Charty.scatter_plot(data: penguins, x: :body_mass_g, y: flipper_length_mm, color: :species, style: :sex)
220
+ ```
221
+
222
+ ![](images/penguins_body_mass_g_flipper_length_mm_species_sex_scatter_plot.png)
223
+
224
+ ### Old-style plotting interface
225
+
58
226
  ```ruby
59
227
  require 'charty'
60
228
  charty = Charty::Plotter.new(:pyplot)
@@ -354,7 +522,7 @@ hist.render("sample_images/hist_pyplot.png")
354
522
 
355
523
  #### Gruff
356
524
 
357
- Not supported
525
+ ![hist_gruff](https://raw.githubusercontent.com/red-data-tools/charty/master/examples/sample_images/hist_gruff.png)
358
526
 
359
527
  #### Rubyplot
360
528