red-palette 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +6 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +7 -0
- data/README.md +23 -0
- data/Rakefile +19 -0
- data/lib/palette.rb +133 -0
- data/lib/palette/colors.rb +60 -0
- data/lib/palette/constants.rb +51 -0
- data/lib/palette/statistics.rb +29 -0
- data/lib/palette/version.rb +3 -0
- data/red-palette.gemspec +43 -0
- data/test/helper.rb +13 -0
- data/test/palette_test.rb +150 -0
- data/test/run.rb +17 -0
- metadata +158 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 72542b2d2b866247433dcdd20f7dcd233e7c5cc8c55b16c13079f370a9092d3a
|
4
|
+
data.tar.gz: 9cf3c3427e80a3a25b33f6a880f009c5a039f30d2b573a7cfd50d322eec3c260
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3914868d96a9f88a85c7e22bcde72596db87998a45f3e44bacda5c1ff635046302709711719b53ab912b87dd2569ba8e5b20b32f9a5b5960ac68697fbf56eee5
|
7
|
+
data.tar.gz: 60c4a27bdce6bb0bf5e1455ddbdbc1437857e8fb7ed799a6e62e8c2cc486579ac51bb38f32235c50fc49e853d64fa6ab245bde1a9aea6d8bd6fc54d3b1523e7e
|
data/.yardopts
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright 2019 Kenta Murata <mrkn@mrkn.jp>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Red Palette
|
2
|
+
|
3
|
+
![](https://github.com/red-data-tools/red-palette/workflows/CI/badge.svg)
|
4
|
+
|
5
|
+
## Description
|
6
|
+
|
7
|
+
Red Palette provides features for dealing with palette.
|
8
|
+
|
9
|
+
## Install
|
10
|
+
|
11
|
+
```console
|
12
|
+
$ gem install red-palette
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
To be described later.
|
18
|
+
|
19
|
+
See the [documentation](https://rubydoc.info/gems/red-colors) for now.
|
20
|
+
|
21
|
+
## License
|
22
|
+
|
23
|
+
The MIT license. See [`LICENSE.txt`](LICENSE.txt) for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/gem_helper"
|
3
|
+
|
4
|
+
base_dir = File.join(File.dirname(__FILE__))
|
5
|
+
|
6
|
+
helper = Bundler::GemHelper.new(base_dir)
|
7
|
+
def helper.version_tag
|
8
|
+
version
|
9
|
+
end
|
10
|
+
|
11
|
+
helper.install
|
12
|
+
spec = helper.gemspec
|
13
|
+
|
14
|
+
desc "Run tests"
|
15
|
+
task :test do
|
16
|
+
ruby("test/run.rb")
|
17
|
+
end
|
18
|
+
|
19
|
+
task default: :test
|
data/lib/palette.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
require "colors"
|
2
|
+
require "numo/narray"
|
3
|
+
|
4
|
+
require_relative "palette/constants"
|
5
|
+
require_relative "palette/colors"
|
6
|
+
require_relative "palette/statistics"
|
7
|
+
|
8
|
+
class Palette
|
9
|
+
include Constants
|
10
|
+
|
11
|
+
# Return a list of colors defining a color palette
|
12
|
+
#
|
13
|
+
# @param palette [nil, String, Palette]
|
14
|
+
# Name of palette or nil to return current palette.
|
15
|
+
# If a Palette is given, input colors are used but
|
16
|
+
# possibly cycled and desaturated.
|
17
|
+
# @param n_colors [Integer, nil]
|
18
|
+
# Number of colors in the palette.
|
19
|
+
# If `nil`, the default will depend on how `palette` is specified.
|
20
|
+
# Named palettes default to 6 colors, but grabbing the current palette
|
21
|
+
# or passing in a list of colors will not change the number of colors
|
22
|
+
# unless this is specified. Asking for more colors than exist in the
|
23
|
+
# palette cause it to cycle.
|
24
|
+
# @param desaturate_factor [Float, nil]
|
25
|
+
# Propotion to desaturate each color by.
|
26
|
+
#
|
27
|
+
# @return [Palette]
|
28
|
+
# Color palette. Behaves like a list.
|
29
|
+
def initialize(palette=nil, n_colors=nil, desaturate_factor: nil)
|
30
|
+
case
|
31
|
+
when palette.nil?
|
32
|
+
@name = nil
|
33
|
+
palette = Colors::ColorData::DEFAULT_COLOR_CYCLE
|
34
|
+
n_colors ||= palette.length
|
35
|
+
else
|
36
|
+
palette = normalize_palette_name(palette)
|
37
|
+
case palette
|
38
|
+
when String
|
39
|
+
@name = palette
|
40
|
+
# Use all colors in a qualitative palette or 6 of another kind
|
41
|
+
n_colors ||= QUAL_PALETTE_SIZES.fetch(palette, 6)
|
42
|
+
case @name
|
43
|
+
when SEABORN_PALETTES.method(:has_key?)
|
44
|
+
palette = self.class.seaborn_colors(@name)
|
45
|
+
when "hls", "HLS", "hsl", "HSL"
|
46
|
+
palette = self.class.hsl_colors(n_colors)
|
47
|
+
when "husl", "HUSL"
|
48
|
+
palette = self.class.husl_colors(n_colors)
|
49
|
+
when /\Ach:/
|
50
|
+
# Cubehelix palette with params specified in string
|
51
|
+
args, kwargs = parse_cubehelix_args(palette)
|
52
|
+
palette = self.class.cubehelix_colors(n_colors, *args, **kwargs)
|
53
|
+
else
|
54
|
+
begin
|
55
|
+
palette = self.class.matplotlib_colors(palette, n_colors)
|
56
|
+
rescue ArgumentError
|
57
|
+
raise ArgumentError,
|
58
|
+
"#{palette} is not a valid palette name"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
else
|
62
|
+
n_colors ||= palette.length
|
63
|
+
end
|
64
|
+
end
|
65
|
+
if desaturate_factor
|
66
|
+
palette = palette.map {|c| Colors.desaturate(c, desaturate_factor) }
|
67
|
+
end
|
68
|
+
|
69
|
+
# Always return as many colors as we asked for
|
70
|
+
@colors = palette.cycle.take(n_colors).freeze
|
71
|
+
@desaturate_factor = desaturate_factor
|
72
|
+
end
|
73
|
+
|
74
|
+
attr_reader :name, :colors, :desaturate_factor
|
75
|
+
|
76
|
+
def n_colors
|
77
|
+
@colors.length
|
78
|
+
end
|
79
|
+
|
80
|
+
# Two palettes are equal if they have the same colors, even if they have
|
81
|
+
# the different names and different desaturate factors.
|
82
|
+
def ==(other)
|
83
|
+
case other
|
84
|
+
when Palette
|
85
|
+
colors == other.colors
|
86
|
+
else
|
87
|
+
super
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def [](i)
|
92
|
+
@palette[i % n_colors]
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_ary
|
96
|
+
@palette.dup
|
97
|
+
end
|
98
|
+
|
99
|
+
private def normalize_palette_name(palette)
|
100
|
+
case palette
|
101
|
+
when String
|
102
|
+
palette
|
103
|
+
when Symbol
|
104
|
+
palette.to_s
|
105
|
+
else
|
106
|
+
palette.to_str
|
107
|
+
end
|
108
|
+
rescue NoMethodError, TypeError
|
109
|
+
palette
|
110
|
+
end
|
111
|
+
|
112
|
+
class << self
|
113
|
+
attr_reader :default
|
114
|
+
|
115
|
+
def default=(args)
|
116
|
+
@default = case args
|
117
|
+
when Palette
|
118
|
+
args
|
119
|
+
when Array
|
120
|
+
case args[0]
|
121
|
+
when Array
|
122
|
+
Palette.new(*args)
|
123
|
+
else
|
124
|
+
Palette.new(args)
|
125
|
+
end
|
126
|
+
else
|
127
|
+
Palette.new(args)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
self.default = Palette.new("deep").freeze
|
133
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class Palette
|
2
|
+
def self.seaborn_colors(name)
|
3
|
+
SEABORN_PALETTES[name].map do |hex_string|
|
4
|
+
Colors::RGB.parse(hex_string)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
# Get a set of evenly spaced colors in HSL hue space.
|
9
|
+
#
|
10
|
+
# @param n_colors [Integer]
|
11
|
+
# The number of colors in the palette
|
12
|
+
# @param h [Numeric]
|
13
|
+
# The hue value of the first color in degree
|
14
|
+
# @param s [Numeric]
|
15
|
+
# The saturation value of the first color (between 0 and 1)
|
16
|
+
# @param l [Numeric]
|
17
|
+
# The lightness value of the first color (between 0 and 1)
|
18
|
+
#
|
19
|
+
# @return [Array<Colors::HSL>]
|
20
|
+
# The array of colors
|
21
|
+
def self.hsl_colors(n_colors=6, h: 3.6r, s: 0.65r, l: 0.6r)
|
22
|
+
hues = Numo::DFloat.linspace(0, 1, n_colors + 1)[0...-1]
|
23
|
+
hues.inplace + (h/360r).to_f
|
24
|
+
hues.inplace % 1
|
25
|
+
hues.inplace - Numo::Int32.cast(hues)
|
26
|
+
(0...n_colors).map {|i| Colors::HSL.new(hues[i]*360r, s, l) }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get a set of evenly spaced colors in HUSL hue space.
|
30
|
+
#
|
31
|
+
# @param n_colors [Integer]
|
32
|
+
# The number of colors in the palette
|
33
|
+
# @param h [Numeric]
|
34
|
+
# The hue value of the first color in degree
|
35
|
+
# @param s [Numeric]
|
36
|
+
# The saturation value of the first color (between 0 and 1)
|
37
|
+
# @param l [Numeric]
|
38
|
+
# The lightness value of the first color (between 0 and 1)
|
39
|
+
#
|
40
|
+
# @return [Array<Colors::HSL>]
|
41
|
+
# The array of colors
|
42
|
+
def self.husl_colors(n_colors=6, h: 3.6r, s: 0.9r, l: 0.65r)
|
43
|
+
hues = Numo::DFloat.linspace(0, 1, n_colors + 1)[0...-1]
|
44
|
+
hues.inplace + (h/360r).to_f
|
45
|
+
hues.inplace % 1
|
46
|
+
hues.inplace * 359
|
47
|
+
(0...n_colors).map {|i| Colors::HUSL.new(hues[i], s, l) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.cubehelix_colors(n_colors, start=0, rot=0.4r, gamma=1.0r, hue=0.8r,
|
51
|
+
light=0.85r, dark=0.15r, reverse=false, as_cmap: false)
|
52
|
+
raise NotImplementedError,
|
53
|
+
"Cubehelix palette has not been implemented"
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.matplotlib_colors(name, n_colors=6)
|
57
|
+
raise NotImplementedError,
|
58
|
+
"Matplotlib's colormap emulation has not been implemented"
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Palette
|
2
|
+
module Constants
|
3
|
+
SEABORN_PALETTES = {
|
4
|
+
"deep" => ["#4C72B0", "#DD8452", "#55A868", "#C44E52", "#8172B3",
|
5
|
+
"#937860", "#DA8BC3", "#8C8C8C", "#CCB974", "#64B5CD"].freeze,
|
6
|
+
"deep6" => ["#4C72B0", "#55A868", "#C44E52",
|
7
|
+
"#8172B3", "#CCB974", "#64B5CD"].freeze,
|
8
|
+
"muted" => ["#4878D0", "#EE854A", "#6ACC64", "#D65F5F", "#956CB4",
|
9
|
+
"#8C613C", "#DC7EC0", "#797979", "#D5BB67", "#82C6E2"].freeze,
|
10
|
+
"muted6" => ["#4878D0", "#6ACC64", "#D65F5F",
|
11
|
+
"#956CB4", "#D5BB67", "#82C6E2"].freeze,
|
12
|
+
"pastel" => ["#A1C9F4", "#FFB482", "#8DE5A1", "#FF9F9B", "#D0BBFF",
|
13
|
+
"#DEBB9B", "#FAB0E4", "#CFCFCF", "#FFFEA3", "#B9F2F0"].freeze,
|
14
|
+
"pastel6" => ["#A1C9F4", "#8DE5A1", "#FF9F9B",
|
15
|
+
"#D0BBFF", "#FFFEA3", "#B9F2F0"].freeze,
|
16
|
+
"bright" => ["#023EFF", "#FF7C00", "#1AC938", "#E8000B", "#8B2BE2",
|
17
|
+
"#9F4800", "#F14CC1", "#A3A3A3", "#FFC400", "#00D7FF"].freeze,
|
18
|
+
"bright6" => ["#023EFF", "#1AC938", "#E8000B",
|
19
|
+
"#8B2BE2", "#FFC400", "#00D7FF"].freeze,
|
20
|
+
"dark" => ["#001C7F", "#B1400D", "#12711C", "#8C0800", "#591E71",
|
21
|
+
"#592F0D", "#A23582", "#3C3C3C", "#B8850A", "#006374"].freeze,
|
22
|
+
"dark6" => ["#001C7F", "#12711C", "#8C0800",
|
23
|
+
"#591E71", "#B8850A", "#006374"].freeze,
|
24
|
+
"colorblind" => ["#0173B2", "#DE8F05", "#029E73", "#D55E00", "#CC78BC",
|
25
|
+
"#CA9161", "#FBAFE4", "#949494", "#ECE133", "#56B4E9"].freeze,
|
26
|
+
"colorblind6" => ["#0173B2", "#029E73", "#D55E00",
|
27
|
+
"#CC78BC", "#ECE133", "#56B4E9"].freeze
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
MPL_QUAL_PALS = {
|
31
|
+
"tab10" => 10,
|
32
|
+
"tab20" => 20,
|
33
|
+
"tab20b" => 20,
|
34
|
+
"tab20c" => 20,
|
35
|
+
"Set1" => 9,
|
36
|
+
"Set2" => 8,
|
37
|
+
"Set3" => 12,
|
38
|
+
"Accent" => 8,
|
39
|
+
"Paired" => 12,
|
40
|
+
"Pastel1" => 9,
|
41
|
+
"Pastel2" => 8,
|
42
|
+
"Dark2" => 8,
|
43
|
+
}.freeze
|
44
|
+
|
45
|
+
QUAL_PALETTE_SIZES = MPL_QUAL_PALS.dup
|
46
|
+
SEABORN_PALETTES.each do |k, v|
|
47
|
+
QUAL_PALETTE_SIZES[k] = v.length
|
48
|
+
end
|
49
|
+
QUAL_PALETTE_SIZES.freeze
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Palette
|
2
|
+
module Statistics
|
3
|
+
begin
|
4
|
+
require "enumerable/statistics"
|
5
|
+
|
6
|
+
def self.mean(enum)
|
7
|
+
enum.mean
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.stdev(enum, population: false)
|
11
|
+
enum.stdev(population: population)
|
12
|
+
end
|
13
|
+
rescue LoadError
|
14
|
+
def self.mean(enum)
|
15
|
+
xs = enum.to_a
|
16
|
+
xs.sum / xs.length.to_f
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.stdev(enum, population: false)
|
20
|
+
xs = enum.to_a
|
21
|
+
n = xs.length
|
22
|
+
mean = xs.sum.to_f / n
|
23
|
+
ddof = population ? 0 : 1
|
24
|
+
var = xs.map {|x| (x - mean)**2 }.sum / (n - ddof)
|
25
|
+
Math.sqrt(var)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/red-palette.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
clean_white_space = lambda do |entry|
|
2
|
+
entry.gsub(/(\A\n+|\n+\z)/, '') + "\n"
|
3
|
+
end
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "lib"))
|
6
|
+
require "palette/version"
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = "red-palette"
|
10
|
+
spec.version = Palette::VERSION
|
11
|
+
spec.homepage = "https://github.com/red-data-tools/red-palette"
|
12
|
+
spec.authors = ["Kenta Murata"]
|
13
|
+
spec.email = ["mrkn@mrkn.jp"]
|
14
|
+
|
15
|
+
readme = File.read("README.md")
|
16
|
+
readme.force_encoding("UTF-8")
|
17
|
+
entries = readme.split(/^\#\#\s(.*)$/)
|
18
|
+
clean_white_space.call(entries[entries.index("Description") + 1])
|
19
|
+
description = clean_white_space.call(entries[entries.index("Description") + 1])
|
20
|
+
spec.summary, spec.description, = description.split(/\n\n+/, 3)
|
21
|
+
spec.license = "MIT"
|
22
|
+
spec.files = [
|
23
|
+
"README.md",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"Rakefile",
|
26
|
+
"Gemfile",
|
27
|
+
"#{spec.name}.gemspec",
|
28
|
+
]
|
29
|
+
spec.files += [".yardopts"]
|
30
|
+
spec.files += Dir.glob("lib/**/*.rb")
|
31
|
+
spec.files += Dir.glob("image/*.*")
|
32
|
+
spec.files += Dir.glob("doc/text/*")
|
33
|
+
spec.test_files += Dir.glob("test/**/*")
|
34
|
+
|
35
|
+
spec.add_dependency("red-colors")
|
36
|
+
spec.add_dependency("numo-narray")
|
37
|
+
|
38
|
+
spec.add_development_dependency("bundler")
|
39
|
+
spec.add_development_dependency("rake")
|
40
|
+
spec.add_development_dependency("test-unit")
|
41
|
+
spec.add_development_dependency("yard")
|
42
|
+
spec.add_development_dependency("kramdown")
|
43
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'palette'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
module TestHelper
|
6
|
+
def assert_near(c1, c2, eps=1e-8)
|
7
|
+
assert_equal(c1.class, c2.class)
|
8
|
+
c1.components.zip(c2.components).each do |x1, x2|
|
9
|
+
x1, x2 = [x1, x2].map(&:to_f)
|
10
|
+
assert { (x1 - x2).abs < eps }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
class PaletteTest < Test::Unit::TestCase
|
2
|
+
include TestHelper
|
3
|
+
|
4
|
+
sub_test_case(".default") do
|
5
|
+
test("the initial value") do
|
6
|
+
assert_equal(Palette.new("deep"), Palette.default)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
test(".default=") do
|
11
|
+
begin
|
12
|
+
save = Palette.default
|
13
|
+
palette = Palette.new("colorblind")
|
14
|
+
Palette.default = palette
|
15
|
+
assert_same(palette, Palette.default)
|
16
|
+
ensure
|
17
|
+
Palette.default = save
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
test("array palette") do
|
22
|
+
palette = Palette.new(["red", "green", "blue"])
|
23
|
+
assert_equal(nil, palette.name)
|
24
|
+
assert_equal(3, palette.n_colors)
|
25
|
+
assert_equal(["red", "green", "blue"], palette.colors)
|
26
|
+
end
|
27
|
+
|
28
|
+
sub_test_case("seaborn's named palette") do
|
29
|
+
test("deep") do
|
30
|
+
palette = Palette.new("deep")
|
31
|
+
assert_equal("deep", palette.name)
|
32
|
+
assert_equal(Palette::QUAL_PALETTE_SIZES["deep"],
|
33
|
+
palette.n_colors)
|
34
|
+
assert_equal(Palette::SEABORN_PALETTES["deep"].map {|c|
|
35
|
+
Colors::RGB.parse(c)
|
36
|
+
},
|
37
|
+
palette.colors)
|
38
|
+
end
|
39
|
+
|
40
|
+
test("pastel6") do
|
41
|
+
palette = Palette.new("pastel6")
|
42
|
+
assert_equal("pastel6", palette.name)
|
43
|
+
assert_equal(Palette::QUAL_PALETTE_SIZES["pastel6"],
|
44
|
+
palette.n_colors)
|
45
|
+
assert_equal(Palette::SEABORN_PALETTES["pastel6"].map {|c|
|
46
|
+
Colors::RGB.parse(c)
|
47
|
+
},
|
48
|
+
palette.colors)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
test("HSL color palette") do
|
53
|
+
assert_equal(6,
|
54
|
+
Palette.new("hsl").n_colors)
|
55
|
+
end
|
56
|
+
|
57
|
+
test("HUSL color palette") do
|
58
|
+
omit("Not implemented yet")
|
59
|
+
assert_equal(6,
|
60
|
+
Palette.new("husl").n_colors)
|
61
|
+
end
|
62
|
+
|
63
|
+
test(".hsl_colors") do
|
64
|
+
palette1 = Palette.hsl_colors(6, h: 0)
|
65
|
+
palette2 = Palette.hsl_colors(6, h: 360/2r)
|
66
|
+
palette2 = palette2[3..-1] + palette2[0...3]
|
67
|
+
palette1.zip(palette2).each do |c1, c2|
|
68
|
+
assert_in_delta(c1.h, c2.h, 1e-6)
|
69
|
+
assert_in_delta(c1.s, c2.s, 1e-6)
|
70
|
+
assert_in_delta(c1.l, c2.l, 1e-6)
|
71
|
+
end
|
72
|
+
|
73
|
+
palette_dark = Palette.hsl_colors(5, l: 0.2)
|
74
|
+
palette_bright = Palette.hsl_colors(5, l: 0.8)
|
75
|
+
palette_dark.zip(palette_bright).each do |c1, c2|
|
76
|
+
s1 = c1.to_rgb.components.sum
|
77
|
+
s2 = c2.to_rgb.components.sum
|
78
|
+
assert do
|
79
|
+
s1 < s2
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
palette_flat = Palette.hsl_colors(5, s: 0.1)
|
84
|
+
palette_bold = Palette.hsl_colors(5, s: 0.9)
|
85
|
+
palette_flat.zip(palette_bold).each do |c1, c2|
|
86
|
+
s1 = Palette::Statistics.stdev(c1.to_rgb.components, population: true).to_f
|
87
|
+
s2 = Palette::Statistics.stdev(c2.to_rgb.components, population: true).to_f
|
88
|
+
assert do
|
89
|
+
s1 < s2
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
test(".husl_colors") do
|
95
|
+
palette1 = Palette.husl_colors(6, h: 0)
|
96
|
+
palette2 = Palette.husl_colors(6, h: 360/2r)
|
97
|
+
palette2 = palette2[3..-1] + palette2[0...3]
|
98
|
+
palette1.zip(palette2).each do |c1, c2|
|
99
|
+
assert_in_delta(c1.h, c2.h, 1e-6)
|
100
|
+
assert_in_delta(c1.s, c2.s, 1e-6)
|
101
|
+
assert_in_delta(c1.l, c2.l, 1e-6)
|
102
|
+
end
|
103
|
+
|
104
|
+
palette_dark = Palette.husl_colors(5, l: 0.2)
|
105
|
+
palette_bright = Palette.husl_colors(5, l: 0.8)
|
106
|
+
palette_dark.zip(palette_bright).each do |c1, c2|
|
107
|
+
s1 = c1.to_rgb.components.sum
|
108
|
+
s2 = c2.to_rgb.components.sum
|
109
|
+
assert do
|
110
|
+
s1 < s2
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
palette_flat = Palette.husl_colors(5, s: 0.1)
|
115
|
+
palette_bold = Palette.husl_colors(5, s: 0.9)
|
116
|
+
palette_flat.zip(palette_bold).each do |c1, c2|
|
117
|
+
s1 = Palette::Statistics.stdev(c1.to_rgb.components)
|
118
|
+
s2 = Palette::Statistics.stdev(c2.to_rgb.components)
|
119
|
+
assert do
|
120
|
+
s1 < s2
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
test(".cubehelix_colors") do
|
126
|
+
omit("Not implemented yet")
|
127
|
+
end
|
128
|
+
|
129
|
+
sub_test_case(".matplotlib_colors") do
|
130
|
+
test("Set3") do
|
131
|
+
omit("Not implemented yet")
|
132
|
+
palette = Palette.new("Set3")
|
133
|
+
assert_equal("Set3", palette.name)
|
134
|
+
assert_equal(Palette::QUAL_PALETTE_SIZES["Set3"],
|
135
|
+
palette.n_colors)
|
136
|
+
assert_equal(Palette::SEABORN_PALETTES["Set3"].map {|c|
|
137
|
+
Colors::RGB.parse(c)
|
138
|
+
},
|
139
|
+
palette.colors)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
test("desaturation feature") do
|
144
|
+
desaturated_colors = Palette.new(["#ff0000", "#00ff0099"], desaturate_factor: 0.8).colors
|
145
|
+
assert_near(Colors::HSL.new(0, 0.8r, 0.5r).to_rgb,
|
146
|
+
desaturated_colors[0])
|
147
|
+
assert_near(Colors::HSLA.new(120r, 0.8r, 0.5r, 0x99/255r).to_rgba,
|
148
|
+
desaturated_colors[1])
|
149
|
+
end
|
150
|
+
end
|
data/test/run.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# TODO
|
4
|
+
# $VERBOSE = true
|
5
|
+
|
6
|
+
require "pathname"
|
7
|
+
|
8
|
+
base_dir = Pathname(__dir__).parent.expand_path
|
9
|
+
|
10
|
+
lib_dir = base_dir + "lib"
|
11
|
+
test_dir = base_dir + "test"
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(lib_dir.to_s)
|
14
|
+
|
15
|
+
require_relative "helper"
|
16
|
+
|
17
|
+
exit(Test::Unit::AutoRunner.run(true, test_dir.to_s))
|
metadata
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: red-palette
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kenta Murata
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: red-colors
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: numo-narray
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: test-unit
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: kramdown
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: ''
|
112
|
+
email:
|
113
|
+
- mrkn@mrkn.jp
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".yardopts"
|
119
|
+
- Gemfile
|
120
|
+
- LICENSE.txt
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- lib/palette.rb
|
124
|
+
- lib/palette/colors.rb
|
125
|
+
- lib/palette/constants.rb
|
126
|
+
- lib/palette/statistics.rb
|
127
|
+
- lib/palette/version.rb
|
128
|
+
- red-palette.gemspec
|
129
|
+
- test/helper.rb
|
130
|
+
- test/palette_test.rb
|
131
|
+
- test/run.rb
|
132
|
+
homepage: https://github.com/red-data-tools/red-palette
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
metadata: {}
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
requirements: []
|
151
|
+
rubygems_version: 3.1.2
|
152
|
+
signing_key:
|
153
|
+
specification_version: 4
|
154
|
+
summary: Red Palette provides features for dealing with palette.
|
155
|
+
test_files:
|
156
|
+
- test/helper.rb
|
157
|
+
- test/palette_test.rb
|
158
|
+
- test/run.rb
|