charty 0.2.1 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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