charty 0.2.8 → 0.2.9
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/charty.gemspec +1 -0
- data/lib/charty/backends/plotly.rb +23 -18
- data/lib/charty/backends/pyplot.rb +43 -0
- data/lib/charty/plot_methods.rb +5 -3
- data/lib/charty/plotters/distribution_plotter.rb +7 -0
- data/lib/charty/plotters/histogram_plotter.rb +91 -35
- data/lib/charty/table_adapters/hash_adapter.rb +5 -0
- data/lib/charty/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37ead1e86203bd6580125f4ed97039c6b512e9ae3037a0bc386743ee436f184c
|
4
|
+
data.tar.gz: a94e66292a866acde67c0cfc51bd8eebd5840af68e2d4112caafce80bdd37ed2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b518be17e0ae85405285fe22022bc698d0c080e08a0682f055ae70c97655ed313038e6e2899b7c961bd73c0afe1b6b0c25bdb2085bd3a66dddd57d3e6245df55
|
7
|
+
data.tar.gz: 0bc460c78d178b098c65ab8737efddac0a8484abd920282d185533b72396f0abad62ea247be9e8af4286a70b7a4dc2069e88ff1675ba446af65b5c67edfb59d8
|
data/charty.gemspec
CHANGED
@@ -569,30 +569,35 @@ module Charty
|
|
569
569
|
probability: "probability".freeze
|
570
570
|
}.freeze
|
571
571
|
|
572
|
-
def univariate_histogram(
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
572
|
+
def univariate_histogram(hist, name, variable_name, stat,
|
573
|
+
alpha, color, key_color, color_mapper,
|
574
|
+
_multiple, _element, _fill, _shrink)
|
575
|
+
value_axis = variable_name
|
576
|
+
case value_axis
|
577
|
+
when :x
|
578
|
+
weights_axis = :y
|
579
|
+
orientation = :v
|
580
|
+
else
|
581
|
+
weights_axis = :x
|
582
|
+
orientation = :h
|
583
|
+
end
|
584
|
+
|
585
|
+
mid_points = hist.edges.each_cons(2).map {|a, b| a + (b - a) / 2 }
|
586
|
+
|
581
587
|
trace = {
|
582
|
-
type:
|
588
|
+
type: :bar,
|
583
589
|
name: name.to_s,
|
584
|
-
|
590
|
+
value_axis => mid_points,
|
591
|
+
weights_axis => hist.weights,
|
585
592
|
orientation: orientation,
|
586
|
-
histnorm: PLOTLY_HISTNORM[stat],
|
587
|
-
"#{variable_name}bins": {
|
588
|
-
start: bin_start,
|
589
|
-
end: bin_end,
|
590
|
-
size: bin_size
|
591
|
-
},
|
592
593
|
opacity: alpha
|
593
594
|
}
|
594
595
|
|
595
|
-
if color
|
596
|
+
if color.nil?
|
597
|
+
trace[:marker] = {
|
598
|
+
color: key_color.to_rgb.to_hex_string
|
599
|
+
}
|
600
|
+
else
|
596
601
|
trace[:marker] = {
|
597
602
|
color: color_mapper[color].to_rgb.to_hex_string
|
598
603
|
}
|
@@ -14,6 +14,7 @@ module Charty
|
|
14
14
|
|
15
15
|
def initialize
|
16
16
|
@pyplot = ::Matplotlib::Pyplot
|
17
|
+
@default_edgecolor = Colors["white"].to_rgb
|
17
18
|
@default_line_width = ::Matplotlib.rcParams["lines.linewidth"]
|
18
19
|
@default_marker_size = ::Matplotlib.rcParams["lines.markersize"]
|
19
20
|
end
|
@@ -575,6 +576,47 @@ module Charty
|
|
575
576
|
min + x * (max - min)
|
576
577
|
end
|
577
578
|
|
579
|
+
def univariate_histogram(hist, name, variable_name, stat,
|
580
|
+
alpha, color, key_color, color_mapper,
|
581
|
+
multiple, element, fill, shrink)
|
582
|
+
mid_points = hist.edges.each_cons(2).map {|a, b| a + (b - a) / 2 }
|
583
|
+
orient = variable_name == :x ? :v : :h
|
584
|
+
width = shrink * (hist.edges[1] - hist.edges[0])
|
585
|
+
|
586
|
+
kw = {align: :edge}
|
587
|
+
|
588
|
+
color = if color.nil?
|
589
|
+
key_color.to_rgb
|
590
|
+
else
|
591
|
+
color_mapper[color].to_rgb
|
592
|
+
end
|
593
|
+
|
594
|
+
alpha = 1r unless fill
|
595
|
+
|
596
|
+
if fill
|
597
|
+
kw[:facecolor] = color.to_rgba(alpha: alpha).to_hex_string
|
598
|
+
if multiple == :stack || multiple == :fill || element == :bars
|
599
|
+
kw[:edgecolor] = @default_edgecolor.to_hex_string
|
600
|
+
else
|
601
|
+
kw[:edgecolor] = color.to_hex_string
|
602
|
+
end
|
603
|
+
elsif element == :bars
|
604
|
+
kw.delete(:facecolor)
|
605
|
+
kw[:edgecolor] = color.to_rgba(alpha: alpha).to_hex_string
|
606
|
+
else
|
607
|
+
kw[:color] = color.to_rgba(alpha: alpha).to_hex_string
|
608
|
+
end
|
609
|
+
|
610
|
+
kw[:label] = name unless name.nil?
|
611
|
+
|
612
|
+
ax = @pyplot.gca
|
613
|
+
if orient == :v
|
614
|
+
ax.bar(mid_points, hist.weights, width, **kw)
|
615
|
+
else
|
616
|
+
ax.barh(mid_points, hist.weights, width, **kw)
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
578
620
|
private def locator_to_legend_entries(locator, limits)
|
579
621
|
vmin, vmax = limits
|
580
622
|
dtype = case vmin
|
@@ -686,6 +728,7 @@ module Charty
|
|
686
728
|
params[key] = kwargs[key] if kwargs.key?(key)
|
687
729
|
end
|
688
730
|
@pyplot.savefig(filename, **params)
|
731
|
+
@pyplot.close
|
689
732
|
end
|
690
733
|
|
691
734
|
def show
|
data/lib/charty/plot_methods.rb
CHANGED
@@ -249,17 +249,16 @@ module Charty
|
|
249
249
|
)
|
250
250
|
end
|
251
251
|
|
252
|
-
def hist_plot(data: nil, x: nil, y: nil, color: nil,
|
252
|
+
def hist_plot(data: nil, x: nil, y: nil, color: nil, weights: nil,
|
253
253
|
stat: :count, bins: :auto,
|
254
|
+
bin_range: nil, common_bins: true,
|
254
255
|
key_color: nil, palette: nil, color_order: nil, color_norm: nil,
|
255
256
|
legend: true, **options, &block)
|
256
257
|
# TODO: support following arguments
|
257
258
|
# - wiehgts
|
258
259
|
# - binwidth
|
259
|
-
# - binrange
|
260
260
|
# - discrete
|
261
261
|
# - cumulative
|
262
|
-
# - common_bins
|
263
262
|
# - common_norm
|
264
263
|
# - multiple
|
265
264
|
# - element
|
@@ -278,8 +277,11 @@ module Charty
|
|
278
277
|
Plotters::HistogramPlotter.new(
|
279
278
|
data: data,
|
280
279
|
variables: { x: x, y: y, color: color },
|
280
|
+
weights: weights,
|
281
281
|
stat: stat,
|
282
282
|
bins: bins,
|
283
|
+
bin_range: bin_range,
|
284
|
+
common_bins: common_bins,
|
283
285
|
key_color: key_color,
|
284
286
|
palette: palette,
|
285
287
|
color_order: color_order,
|
@@ -14,6 +14,12 @@ module Charty
|
|
14
14
|
setup_variables
|
15
15
|
end
|
16
16
|
|
17
|
+
attr_reader :weights
|
18
|
+
|
19
|
+
def weights=(val)
|
20
|
+
@weights = check_dimension(val, :weights)
|
21
|
+
end
|
22
|
+
|
17
23
|
attr_reader :variables
|
18
24
|
|
19
25
|
attr_reader :color_norm
|
@@ -103,6 +109,7 @@ module Charty
|
|
103
109
|
x: self.x,
|
104
110
|
y: self.y,
|
105
111
|
color: self.color,
|
112
|
+
weights: self.weights
|
106
113
|
}.each do |key, val|
|
107
114
|
next if val.nil?
|
108
115
|
|
@@ -12,16 +12,6 @@ module Charty
|
|
12
12
|
([:x, :y] & self.variables.keys)[0]
|
13
13
|
end
|
14
14
|
|
15
|
-
attr_reader :weights
|
16
|
-
|
17
|
-
def weights=(val)
|
18
|
-
@weights = check_weights(val)
|
19
|
-
end
|
20
|
-
|
21
|
-
private def check_weights(val)
|
22
|
-
raise NotImplementedError, "weights is not supported yet"
|
23
|
-
end
|
24
|
-
|
25
15
|
attr_reader :stat
|
26
16
|
|
27
17
|
def stat=(val)
|
@@ -65,10 +55,44 @@ module Charty
|
|
65
55
|
end
|
66
56
|
|
67
57
|
# TODO: bin_width
|
68
|
-
|
58
|
+
|
59
|
+
attr_reader :bin_range
|
60
|
+
|
61
|
+
def bin_range=(val)
|
62
|
+
@bin_range = check_bin_range(val)
|
63
|
+
end
|
64
|
+
|
65
|
+
private def check_bin_range(val)
|
66
|
+
case val
|
67
|
+
when nil, Range
|
68
|
+
return val
|
69
|
+
when Array
|
70
|
+
if val.length == 2
|
71
|
+
val.each_with_index do |v, i|
|
72
|
+
check_number(v, "bin_range[#{i}]")
|
73
|
+
end
|
74
|
+
return val
|
75
|
+
else
|
76
|
+
amount = val.length < 2 ? "few" : "many"
|
77
|
+
raise ArgumentError,
|
78
|
+
"Too #{amount} items in `bin_range` array (%p for 2)" % val.length
|
79
|
+
end
|
80
|
+
else
|
81
|
+
raise ArgumentError,
|
82
|
+
"Invalid value for `bin_range` " +
|
83
|
+
"(%p for a range or a pair of numbers)" % val
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
69
87
|
# TODO: discrete
|
70
88
|
# TODO: cumulative
|
71
|
-
|
89
|
+
|
90
|
+
attr_reader :common_bins
|
91
|
+
|
92
|
+
def common_bins=(val)
|
93
|
+
@common_bins = check_boolean(val, :common_bins)
|
94
|
+
end
|
95
|
+
|
72
96
|
# TODO: common_norm
|
73
97
|
|
74
98
|
attr_reader :multiple
|
@@ -127,28 +151,52 @@ module Charty
|
|
127
151
|
private def draw_univariate_histogram(backend)
|
128
152
|
map_color(palette: palette, order: color_order, norm: color_norm)
|
129
153
|
|
154
|
+
key_color = self.key_color
|
155
|
+
if key_color.nil? && !self.variables.key?(:color)
|
156
|
+
palette = case self.palette
|
157
|
+
when Palette
|
158
|
+
self.palette
|
159
|
+
when nil
|
160
|
+
Palette.default
|
161
|
+
else
|
162
|
+
Palette[self.palette]
|
163
|
+
end
|
164
|
+
key_color = palette[0]
|
165
|
+
end
|
166
|
+
|
130
167
|
# TODO: calculate histogram here and use bar plot to visualize
|
131
168
|
data_variable = self.univariate_variable
|
132
169
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
170
|
+
if common_bins
|
171
|
+
all_data = processed_data.drop_na
|
172
|
+
all_observations = all_data[data_variable].to_a
|
173
|
+
|
174
|
+
bins = self.bins
|
175
|
+
bins = 10 if self.variables.key?(:color) && bins == :auto
|
176
|
+
|
177
|
+
case bins
|
178
|
+
when Integer
|
179
|
+
case bin_range
|
180
|
+
when Range
|
181
|
+
start = bin_range.begin
|
182
|
+
stop = bin_range.end
|
183
|
+
when Array
|
184
|
+
start, stop = bin_range.minmax
|
185
|
+
end
|
186
|
+
data_range = all_observations.minmax
|
187
|
+
start ||= data_range[0]
|
188
|
+
stop ||= data_range[1]
|
189
|
+
if start == stop
|
190
|
+
start -= 0.5
|
191
|
+
stop += 0.5
|
192
|
+
end
|
193
|
+
common_bin_edges = Linspace.new(start .. stop, bins + 1).map(&:to_f)
|
194
|
+
else
|
195
|
+
params = {}
|
196
|
+
params[:weights] = all_data[:weights].to_a if all_data.column?(:weights)
|
197
|
+
h = Statistics.histogram(all_observations, bins, **params)
|
198
|
+
common_bin_edges = h.edges
|
199
|
+
end
|
152
200
|
end
|
153
201
|
|
154
202
|
if self.variables.key?(:color)
|
@@ -158,12 +206,16 @@ module Charty
|
|
158
206
|
end
|
159
207
|
|
160
208
|
each_subset([:color], processed: true) do |sub_vars, sub_data|
|
161
|
-
name = sub_vars[:color]
|
162
209
|
observations = sub_data[data_variable].drop_na.to_a
|
210
|
+
params = {}
|
211
|
+
params[:weights] = sub_data[:weights].to_a if sub_data.column?(:weights)
|
212
|
+
params[:edges] = common_bin_edges if common_bin_edges
|
213
|
+
hist = Statistics.histogram(observations, bins, **params)
|
163
214
|
|
164
|
-
|
165
|
-
|
166
|
-
name, @color_mapper
|
215
|
+
name = sub_vars[:color]
|
216
|
+
backend.univariate_histogram(hist, name, data_variable, stat,
|
217
|
+
alpha, name, key_color, @color_mapper,
|
218
|
+
multiple, :bars, true, 1r)
|
167
219
|
end
|
168
220
|
end
|
169
221
|
|
@@ -179,6 +231,10 @@ module Charty
|
|
179
231
|
end
|
180
232
|
backend.set_ylabel(ylabel) if ylabel
|
181
233
|
backend.set_xlabel(xlabel) if xlabel
|
234
|
+
|
235
|
+
if self.variables.key?(:color)
|
236
|
+
backend.legend(loc: :best, title: self.variables[:color])
|
237
|
+
end
|
182
238
|
end
|
183
239
|
end
|
184
240
|
end
|
@@ -20,6 +20,8 @@ module Charty
|
|
20
20
|
end
|
21
21
|
when Hash
|
22
22
|
true
|
23
|
+
when ->(x) { defined?(CSV::Table) && x.is_a?(CSV::Table) }
|
24
|
+
true
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
@@ -79,6 +81,9 @@ module Charty
|
|
79
81
|
else
|
80
82
|
unsupported_data_format
|
81
83
|
end
|
84
|
+
when ->(x) { defined?(CSV::Table) && x.is_a?(CSV::Table) }
|
85
|
+
columns ||= data.headers
|
86
|
+
arrays = data.headers.map {|x| data[x] }
|
82
87
|
else
|
83
88
|
unsupported_data_format
|
84
89
|
end
|
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.9
|
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: 2021-06-
|
13
|
+
date: 2021-06-24 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: red-colors
|
@@ -208,6 +208,20 @@ dependencies:
|
|
208
208
|
- - ">="
|
209
209
|
- !ruby/object:Gem::Version
|
210
210
|
version: 0.7.0
|
211
|
+
- !ruby/object:Gem::Dependency
|
212
|
+
name: csv
|
213
|
+
requirement: !ruby/object:Gem::Requirement
|
214
|
+
requirements:
|
215
|
+
- - ">="
|
216
|
+
- !ruby/object:Gem::Version
|
217
|
+
version: '0'
|
218
|
+
type: :development
|
219
|
+
prerelease: false
|
220
|
+
version_requirements: !ruby/object:Gem::Requirement
|
221
|
+
requirements:
|
222
|
+
- - ">="
|
223
|
+
- !ruby/object:Gem::Version
|
224
|
+
version: '0'
|
211
225
|
description: Visualizing your data in a simple way.
|
212
226
|
email:
|
213
227
|
- youchan01@gmail.com
|