charty 0.2.1 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) 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/Dockerfile.dev +9 -1
  6. data/Gemfile +18 -0
  7. data/README.md +177 -9
  8. data/Rakefile +4 -5
  9. data/charty.gemspec +10 -5
  10. data/examples/palette.rb +1 -1
  11. data/examples/sample_images/hist_gruff.png +0 -0
  12. data/images/penguins_body_mass_g_flipper_length_mm_scatter_plot.png +0 -0
  13. data/images/penguins_body_mass_g_flipper_length_mm_species_scatter_plot.png +0 -0
  14. data/images/penguins_body_mass_g_flipper_length_mm_species_sex_scatter_plot.png +0 -0
  15. data/images/penguins_species_body_mass_g_bar_plot_h.png +0 -0
  16. data/images/penguins_species_body_mass_g_bar_plot_v.png +0 -0
  17. data/images/penguins_species_body_mass_g_box_plot_h.png +0 -0
  18. data/images/penguins_species_body_mass_g_box_plot_v.png +0 -0
  19. data/images/penguins_species_body_mass_g_sex_bar_plot_v.png +0 -0
  20. data/images/penguins_species_body_mass_g_sex_box_plot_v.png +0 -0
  21. data/lib/charty.rb +9 -2
  22. data/lib/charty/backends.rb +1 -0
  23. data/lib/charty/backends/bokeh.rb +2 -2
  24. data/lib/charty/backends/google_charts.rb +1 -1
  25. data/lib/charty/backends/gruff.rb +14 -3
  26. data/lib/charty/backends/plotly.rb +731 -32
  27. data/lib/charty/backends/plotly_helpers/html_renderer.rb +203 -0
  28. data/lib/charty/backends/plotly_helpers/notebook_renderer.rb +86 -0
  29. data/lib/charty/backends/plotly_helpers/plotly_renderer.rb +121 -0
  30. data/lib/charty/backends/pyplot.rb +515 -67
  31. data/lib/charty/backends/rubyplot.rb +1 -1
  32. data/lib/charty/backends/unicode_plot.rb +79 -0
  33. data/lib/charty/cache_dir.rb +27 -0
  34. data/lib/charty/dash_pattern_generator.rb +57 -0
  35. data/lib/charty/index.rb +213 -0
  36. data/lib/charty/iruby_helper.rb +18 -0
  37. data/lib/charty/linspace.rb +1 -1
  38. data/lib/charty/plot_methods.rb +283 -8
  39. data/lib/charty/plotter.rb +2 -2
  40. data/lib/charty/plotters.rb +11 -0
  41. data/lib/charty/plotters/abstract_plotter.rb +188 -18
  42. data/lib/charty/plotters/bar_plotter.rb +189 -7
  43. data/lib/charty/plotters/box_plotter.rb +64 -11
  44. data/lib/charty/plotters/categorical_plotter.rb +272 -40
  45. data/lib/charty/plotters/count_plotter.rb +7 -0
  46. data/lib/charty/plotters/distribution_plotter.rb +143 -0
  47. data/lib/charty/plotters/estimation_support.rb +84 -0
  48. data/lib/charty/plotters/histogram_plotter.rb +182 -0
  49. data/lib/charty/plotters/line_plotter.rb +300 -0
  50. data/lib/charty/plotters/random_support.rb +25 -0
  51. data/lib/charty/plotters/relational_plotter.rb +635 -0
  52. data/lib/charty/plotters/scatter_plotter.rb +80 -0
  53. data/lib/charty/plotters/vector_plotter.rb +6 -0
  54. data/lib/charty/statistics.rb +96 -2
  55. data/lib/charty/table.rb +160 -15
  56. data/lib/charty/table_adapters.rb +2 -0
  57. data/lib/charty/table_adapters/active_record_adapter.rb +17 -9
  58. data/lib/charty/table_adapters/base_adapter.rb +166 -0
  59. data/lib/charty/table_adapters/daru_adapter.rb +39 -3
  60. data/lib/charty/table_adapters/datasets_adapter.rb +13 -2
  61. data/lib/charty/table_adapters/hash_adapter.rb +141 -16
  62. data/lib/charty/table_adapters/narray_adapter.rb +25 -6
  63. data/lib/charty/table_adapters/nmatrix_adapter.rb +15 -5
  64. data/lib/charty/table_adapters/pandas_adapter.rb +163 -0
  65. data/lib/charty/util.rb +28 -0
  66. data/lib/charty/vector.rb +69 -0
  67. data/lib/charty/vector_adapters.rb +187 -0
  68. data/lib/charty/vector_adapters/array_adapter.rb +101 -0
  69. data/lib/charty/vector_adapters/daru_adapter.rb +163 -0
  70. data/lib/charty/vector_adapters/narray_adapter.rb +182 -0
  71. data/lib/charty/vector_adapters/nmatrix_adapter.rb +37 -0
  72. data/lib/charty/vector_adapters/numpy_adapter.rb +168 -0
  73. data/lib/charty/vector_adapters/pandas_adapter.rb +199 -0
  74. data/lib/charty/version.rb +1 -1
  75. metadata +105 -24
  76. data/lib/charty/palette.rb +0 -235
@@ -1,235 +0,0 @@
1
- require "numo/narray"
2
-
3
- module Charty
4
- class Palette
5
- SEABORN_PALETTES = {
6
- "deep" => ["#4C72B0", "#DD8452", "#55A868", "#C44E52", "#8172B3",
7
- "#937860", "#DA8BC3", "#8C8C8C", "#CCB974", "#64B5CD"].freeze,
8
- "deep6" => ["#4C72B0", "#55A868", "#C44E52",
9
- "#8172B3", "#CCB974", "#64B5CD"].freeze,
10
- "muted" => ["#4878D0", "#EE854A", "#6ACC64", "#D65F5F", "#956CB4",
11
- "#8C613C", "#DC7EC0", "#797979", "#D5BB67", "#82C6E2"].freeze,
12
- "muted6" => ["#4878D0", "#6ACC64", "#D65F5F",
13
- "#956CB4", "#D5BB67", "#82C6E2"].freeze,
14
- "pastel" => ["#A1C9F4", "#FFB482", "#8DE5A1", "#FF9F9B", "#D0BBFF",
15
- "#DEBB9B", "#FAB0E4", "#CFCFCF", "#FFFEA3", "#B9F2F0"].freeze,
16
- "pastel6" => ["#A1C9F4", "#8DE5A1", "#FF9F9B",
17
- "#D0BBFF", "#FFFEA3", "#B9F2F0"].freeze,
18
- "bright" => ["#023EFF", "#FF7C00", "#1AC938", "#E8000B", "#8B2BE2",
19
- "#9F4800", "#F14CC1", "#A3A3A3", "#FFC400", "#00D7FF"].freeze,
20
- "bright6" => ["#023EFF", "#1AC938", "#E8000B",
21
- "#8B2BE2", "#FFC400", "#00D7FF"].freeze,
22
- "dark" => ["#001C7F", "#B1400D", "#12711C", "#8C0800", "#591E71",
23
- "#592F0D", "#A23582", "#3C3C3C", "#B8850A", "#006374"].freeze,
24
- "dark6" => ["#001C7F", "#12711C", "#8C0800",
25
- "#591E71", "#B8850A", "#006374"].freeze,
26
- "colorblind" => ["#0173B2", "#DE8F05", "#029E73", "#D55E00", "#CC78BC",
27
- "#CA9161", "#FBAFE4", "#949494", "#ECE133", "#56B4E9"].freeze,
28
- "colorblind6" => ["#0173B2", "#029E73", "#D55E00",
29
- "#CC78BC", "#ECE133", "#56B4E9"].freeze
30
- }.freeze
31
-
32
- MPL_QUAL_PALS = {
33
- "tab10" => 10,
34
- "tab20" => 20,
35
- "tab20b" => 20,
36
- "tab20c" => 20,
37
- "Set1" => 9,
38
- "Set2" => 8,
39
- "Set3" => 12,
40
- "Accent" => 8,
41
- "Paired" => 12,
42
- "Pastel1" => 9,
43
- "Pastel2" => 8,
44
- "Dark2" => 8,
45
- }.freeze
46
-
47
- QUAL_PALETTE_SIZES = MPL_QUAL_PALS.dup
48
- SEABORN_PALETTES.each do |k, v|
49
- QUAL_PALETTE_SIZES[k] = v.length
50
- end
51
- QUAL_PALETTE_SIZES.freeze
52
-
53
- def self.seaborn_colors(name)
54
- SEABORN_PALETTES[name].map do |hex_string|
55
- Colors::RGB.parse(hex_string)
56
- end
57
- end
58
-
59
- # Get a set of evenly spaced colors in HSL hue space.
60
- #
61
- # @param n_colors [Integer]
62
- # The number of colors in the palette
63
- # @param h [Numeric]
64
- # The hue value of the first color in degree
65
- # @param s [Numeric]
66
- # The saturation value of the first color (between 0 and 1)
67
- # @param l [Numeric]
68
- # The lightness value of the first color (between 0 and 1)
69
- #
70
- # @return [Array<Colors::HSL>]
71
- # The array of colors
72
- def self.hsl_colors(n_colors=6, h: 3.6r, s: 0.65r, l: 0.6r)
73
- hues = Numo::DFloat.linspace(0, 1, n_colors + 1)[0...-1]
74
- hues.inplace + (h/360r).to_f
75
- hues.inplace % 1
76
- hues.inplace - Numo::Int32.cast(hues)
77
- (0...n_colors).map {|i| Colors::HSL.new(hues[i]*360r, s, l) }
78
- end
79
-
80
- # Get a set of evenly spaced colors in HUSL hue space.
81
- #
82
- # @param n_colors [Integer]
83
- # The number of colors in the palette
84
- # @param h [Numeric]
85
- # The hue value of the first color in degree
86
- # @param s [Numeric]
87
- # The saturation value of the first color (between 0 and 1)
88
- # @param l [Numeric]
89
- # The lightness value of the first color (between 0 and 1)
90
- #
91
- # @return [Array<Colors::HSL>]
92
- # The array of colors
93
- def self.husl_colors(n_colors=6, h: 3.6r, s: 0.9r, l: 0.65r)
94
- hues = Numo::DFloat.linspace(0, 1, n_colors + 1)[0...-1]
95
- hues.inplace + (h/360r).to_f
96
- hues.inplace % 1
97
- hues.inplace * 359
98
- (0...n_colors).map {|i| Colors::HUSL.new(hues[i], s, l) }
99
- end
100
-
101
- def self.cubehelix_colors(n_colors, start=0, rot=0.4r, gamma=1.0r, hue=0.8r,
102
- light=0.85r, dark=0.15r, reverse=false, as_cmap: false)
103
- raise NotImplementedError,
104
- "Cubehelix palette has not been implemented"
105
- end
106
-
107
- def self.matplotlib_colors(name, n_colors=6)
108
- raise NotImplementedError,
109
- "Matplotlib's colormap emulation has not been implemented"
110
- end
111
-
112
- # Return a list of colors defining a color palette
113
- #
114
- # @param palette [nil, String, Palette]
115
- # Name of palette or nil to return current palette.
116
- # If a Palette is given, input colors are used but
117
- # possibly cycled and desaturated.
118
- # @param n_colors [Integer, nil]
119
- # Number of colors in the palette.
120
- # If `nil`, the default will depend on how `palette` is specified.
121
- # Named palettes default to 6 colors, but grabbing the current palette
122
- # or passing in a list of colors will not change the number of colors
123
- # unless this is specified. Asking for more colors than exist in the
124
- # palette cause it to cycle.
125
- # @param desaturate_factor [Float, nil]
126
- # Propotion to desaturate each color by.
127
- #
128
- # @return [Palette]
129
- # Color palette. Behaves like a list.
130
- def initialize(palette=nil, n_colors=nil, desaturate_factor: nil)
131
- case
132
- when palette.nil?
133
- @name = nil
134
- palette = Colors::ColorDate::DEFAULT_COLOR_CYCLE
135
- n_colors ||= palette.length
136
- else
137
- palette = normalize_palette_name(palette)
138
- case palette
139
- when String
140
- @name = palette
141
- # Use all colors in a qualitative palette or 6 of another kind
142
- n_colors ||= QUAL_PALETTE_SIZES.fetch(palette, 6)
143
- case @name
144
- when SEABORN_PALETTES.method(:has_key?)
145
- palette = self.class.seaborn_colors(@name)
146
- when "hls", "HLS", "hsl", "HSL"
147
- palette = self.class.hsl_colors(n_colors)
148
- when "husl", "HUSL"
149
- palette = self.class.husl_colors(n_colors)
150
- when /\Ach:/
151
- # Cubehelix palette with params specified in string
152
- args, kwargs = parse_cubehelix_args(palette)
153
- palette = self.class.cubehelix_colors(n_colors, *args, **kwargs)
154
- else
155
- begin
156
- palette = self.class.matplotlib_colors(palette, n_colors)
157
- rescue ArgumentError
158
- raise ArgumentError,
159
- "#{palette} is not a valid palette name"
160
- end
161
- end
162
- else
163
- n_colors ||= palette.length
164
- end
165
- end
166
- if desaturate_factor
167
- palette = palette.map {|c| Colors.desaturate(c, desaturate_factor) }
168
- end
169
-
170
- # Always return as many colors as we asked for
171
- @colors = palette.cycle.take(n_colors).freeze
172
- @desaturate_factor = desaturate_factor
173
- end
174
-
175
- attr_reader :name, :colors, :desaturate_factor
176
-
177
- def n_colors
178
- @colors.length
179
- end
180
-
181
- # Two palettes are equal if they have the same colors, even if they have
182
- # the different names and different desaturate factors.
183
- def ==(other)
184
- case other
185
- when Palette
186
- colors == other.colors
187
- else
188
- super
189
- end
190
- end
191
-
192
- def [](i)
193
- @palette[i % n_colors]
194
- end
195
-
196
- def to_ary
197
- @palette.dup
198
- end
199
-
200
- private def normalize_palette_name(palette)
201
- case palette
202
- when String
203
- palette
204
- when Symbol
205
- palette.to_s
206
- else
207
- palette.to_str
208
- end
209
- rescue NoMethodError, TypeError
210
- palette
211
- end
212
-
213
- class << self
214
- attr_reader :default
215
-
216
- def default=(args)
217
- @default = case args
218
- when Palette
219
- args
220
- when Array
221
- case args[0]
222
- when Array
223
- Palette.new(*args)
224
- else
225
- Palette.new(args)
226
- end
227
- else
228
- Palette.new(args)
229
- end
230
- end
231
- end
232
-
233
- self.default = Palette.new("deep").freeze
234
- end
235
- end