charty 0.2.1 → 0.2.3
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.
- checksums.yaml +4 -4
- data/Dockerfile.dev +9 -1
- data/README.md +5 -5
- data/charty.gemspec +1 -0
- data/examples/palette.rb +1 -1
- data/lib/charty.rb +1 -1
- data/lib/charty/backends.rb +1 -0
- data/lib/charty/backends/pyplot.rb +1 -1
- data/lib/charty/backends/unicode_plot.rb +79 -0
- data/lib/charty/plotters/abstract_plotter.rb +2 -2
- data/lib/charty/version.rb +1 -1
- metadata +18 -4
- data/lib/charty/palette.rb +0 -235
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2b78866e47f947e7cad0c06c3f53418ff07fa6fccce7941b53eb63f70cb8db0
|
4
|
+
data.tar.gz: 39c01144436ceee129c4d938ca8607b15c17292205f4f22da936442f89b2b2ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e83c4308b434b0e3b43e7ed083eefe249b46c3333be00501adee2bd299d4a6e34a78fa2c913f77876cf4ba1448468b553256cd68e22e8a0fe90b5d85b6daaec
|
7
|
+
data.tar.gz: e95895415c62bf352b6bdde4be7d04b7d12278a74a6e1e927376c99b2afc30a81c223e77c3f14848873d2f822233aa7557c4119471eba372af80d61db21756ba
|
data/Dockerfile.dev
CHANGED
data/README.md
CHANGED
@@ -43,14 +43,14 @@ sudo python3 -m pip install -U pip matplotlib
|
|
43
43
|
e.g.
|
44
44
|
|
45
45
|
```
|
46
|
-
$ docker build -f ./Dockerfile.dev -t charty-dev:
|
47
|
-
$ docker run --rm -v $
|
48
|
-
$ docker run -it -v $
|
46
|
+
$ docker build -f ./Dockerfile.dev -t charty-dev:latest .
|
47
|
+
$ docker run --rm -v $(pwd):/charty charty-dev:latest bundle install
|
48
|
+
$ docker run --rm -it -v $(pwd):/charty charty-dev:latest ./bin/console
|
49
49
|
irb(main):001:0> Charty::VERSION
|
50
|
-
=> "0.
|
50
|
+
=> "0.2.2"
|
51
51
|
|
52
52
|
# When using jupyter notebook
|
53
|
-
$ docker run -it -v $
|
53
|
+
$ docker run --rm -it -v $(pwd):/charty -p 8888:8888 charty-dev:latest
|
54
54
|
```
|
55
55
|
|
56
56
|
## Usage
|
data/charty.gemspec
CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.require_paths = ["lib"]
|
28
28
|
|
29
29
|
spec.add_dependency "red-colors"
|
30
|
+
spec.add_dependency "red-palette", ">= 0.2.0"
|
30
31
|
spec.add_development_dependency "bundler", ">= 1.16"
|
31
32
|
spec.add_development_dependency "rake"
|
32
33
|
spec.add_development_dependency "test-unit"
|
data/examples/palette.rb
CHANGED
data/lib/charty.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative "charty/version"
|
2
2
|
|
3
3
|
require "colors"
|
4
|
+
require "palette"
|
4
5
|
|
5
6
|
require_relative "charty/backends"
|
6
7
|
require_relative "charty/backend_methods"
|
@@ -9,7 +10,6 @@ require_relative "charty/layout"
|
|
9
10
|
require_relative "charty/linspace"
|
10
11
|
require_relative "charty/plotters"
|
11
12
|
require_relative "charty/plot_methods"
|
12
|
-
require_relative "charty/palette"
|
13
13
|
require_relative "charty/table_adapters"
|
14
14
|
require_relative "charty/table"
|
15
15
|
require_relative "charty/statistics"
|
data/lib/charty/backends.rb
CHANGED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module Charty
|
4
|
+
module Backends
|
5
|
+
class UnicodePlot
|
6
|
+
Backends.register(:unicode_plot, self)
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def prepare
|
10
|
+
require 'unicode_plot'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def begin_figure
|
15
|
+
@figure = nil
|
16
|
+
@layout = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def bar(bar_pos, values, color: nil)
|
20
|
+
@figure = {
|
21
|
+
type: :bar,
|
22
|
+
bar_pos: bar_pos,
|
23
|
+
values: values
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def box_plot(plot_data, positions, color:, gray:)
|
28
|
+
@figure = { type: :box, data: plot_data }
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_xlabel(label)
|
32
|
+
@layout[:xlabel] = label
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_ylabel(label)
|
36
|
+
@layout[:ylabel] = label
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_xticks(values)
|
40
|
+
@layout[:xticks] = values
|
41
|
+
end
|
42
|
+
|
43
|
+
def set_xtick_labels(values)
|
44
|
+
@layout[:xtick_labels] = values
|
45
|
+
end
|
46
|
+
|
47
|
+
def set_xlim(min, max)
|
48
|
+
@layout[:xlim] = [min, max]
|
49
|
+
end
|
50
|
+
|
51
|
+
def disable_xaxis_grid
|
52
|
+
# do nothing
|
53
|
+
end
|
54
|
+
|
55
|
+
def show
|
56
|
+
case @figure[:type]
|
57
|
+
when :bar
|
58
|
+
plot = ::UnicodePlot.barplot(@layout[:xtick_labels], @figure[:values], xlabel: @layout[:xlabel])
|
59
|
+
when :box
|
60
|
+
plot = ::UnicodePlot.boxplot(@layout[:xtick_labels], @figure[:data], xlabel: @layout[:xlabel])
|
61
|
+
end
|
62
|
+
sio = StringIO.new
|
63
|
+
class << sio
|
64
|
+
def tty?; true; end
|
65
|
+
end
|
66
|
+
plot.render(sio)
|
67
|
+
sio.string
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def show_bar(sio, figure, i)
|
73
|
+
end
|
74
|
+
|
75
|
+
def show_box(sio, figure, i)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -40,12 +40,12 @@ module Charty
|
|
40
40
|
|
41
41
|
def palette=(palette)
|
42
42
|
@palette = case palette
|
43
|
-
when nil,
|
43
|
+
when nil, Palette, Symbol, String
|
44
44
|
palette
|
45
45
|
else
|
46
46
|
raise ArgumentError,
|
47
47
|
"invalid type for palette (given #{palette.class}, " +
|
48
|
-
"expected
|
48
|
+
"expected Palette, Symbol, or String)"
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
data/lib/charty/version.rb
CHANGED
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.2.
|
4
|
+
version: 0.2.3
|
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: 2020-
|
13
|
+
date: 2020-02-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: red-colors
|
@@ -26,6 +26,20 @@ dependencies:
|
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: '0'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: red-palette
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 0.2.0
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.2.0
|
29
43
|
- !ruby/object:Gem::Dependency
|
30
44
|
name: bundler
|
31
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -235,9 +249,9 @@ files:
|
|
235
249
|
- lib/charty/backends/plotly.rb
|
236
250
|
- lib/charty/backends/pyplot.rb
|
237
251
|
- lib/charty/backends/rubyplot.rb
|
252
|
+
- lib/charty/backends/unicode_plot.rb
|
238
253
|
- lib/charty/layout.rb
|
239
254
|
- lib/charty/linspace.rb
|
240
|
-
- lib/charty/palette.rb
|
241
255
|
- lib/charty/plot_methods.rb
|
242
256
|
- lib/charty/plotter.rb
|
243
257
|
- lib/charty/plotters.rb
|
@@ -274,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
274
288
|
- !ruby/object:Gem::Version
|
275
289
|
version: '0'
|
276
290
|
requirements: []
|
277
|
-
rubygems_version: 3.
|
291
|
+
rubygems_version: 3.1.2
|
278
292
|
signing_key:
|
279
293
|
specification_version: 4
|
280
294
|
summary: Visualizing your data in a simple way.
|
data/lib/charty/palette.rb
DELETED
@@ -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
|