red-colors 0.1.3 → 0.2.0
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/lib/colors.rb +5 -0
- data/lib/colors/abstract_color.rb +4 -0
- data/lib/colors/colormap.rb +131 -0
- data/lib/colors/linear_segmented_colormap.rb +119 -0
- data/lib/colors/listed_colormap.rb +41 -0
- data/lib/colors/utils.rb +18 -0
- data/lib/colors/version.rb +1 -1
- data/test/test-linear-segmented-colormap.rb +119 -0
- data/test/test-listed-colormap.rb +115 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 161a952cf581167db1ac2391f1a4f80c83affbc838efdfc7c525587c0c1c8cdb
|
4
|
+
data.tar.gz: b0aa23b1537ded3aa6484eaffd646877da5c53b784a721d7a324c94788ecb842
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e244463b3bd3137808915397688141c67d99298290484c91f94be576b1821f94ad6ce9181a5518ce8d77faddb9a37dbaa0f6c462d1009e7d7bfa6a887fa678fd
|
7
|
+
data.tar.gz: 802cef85dc8c270094812522afffe5571833a2b044145132902939edb5bf118a740a36d07b40583ccfd3ab0f94ec97ccc5f9b8891f00a63b348bfe4519d7dda5
|
data/lib/colors.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative "colors/utils"
|
1
2
|
require_relative "colors/alpha_component"
|
2
3
|
require_relative "colors/convert"
|
3
4
|
require_relative "colors/helper"
|
@@ -15,6 +16,10 @@ require_relative "colors/xyz"
|
|
15
16
|
require_relative "colors/color_data"
|
16
17
|
require_relative "colors/named_colors"
|
17
18
|
|
19
|
+
require_relative "colors/colormap"
|
20
|
+
require_relative "colors/listed_colormap"
|
21
|
+
require_relative "colors/linear_segmented_colormap"
|
22
|
+
|
18
23
|
module Colors
|
19
24
|
# ITU-R BT.709 D65 white point
|
20
25
|
# See https://en.wikipedia.org/wiki/Rec._709 for details
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module Colors
|
2
|
+
class Colormap
|
3
|
+
def initialize(name, n_colors)
|
4
|
+
@name = name
|
5
|
+
@n_colors = n_colors.to_int
|
6
|
+
@bad_color = RGBA.new(0r, 0r, 0r, 0r)
|
7
|
+
@under_color = nil
|
8
|
+
@over_color = nil
|
9
|
+
@under_index = self.n_colors
|
10
|
+
@over_index = self.n_colors + 1
|
11
|
+
@bad_index = self.n_colors + 2
|
12
|
+
@initialized = false
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :name, :n_colors
|
16
|
+
|
17
|
+
def [](x)
|
18
|
+
init_colormap unless @initialized
|
19
|
+
|
20
|
+
xs = Array(x)
|
21
|
+
scalar_p = (xs.length == 1) && xs[0] == x
|
22
|
+
|
23
|
+
if all_ratio?(xs)
|
24
|
+
xs.map! do |v|
|
25
|
+
v *= self.n_colors
|
26
|
+
v = -1 if v < 0
|
27
|
+
v = self.n_colors - 1 if v == self.n_colors
|
28
|
+
v.clamp(-1, self.n_colors).to_i
|
29
|
+
end
|
30
|
+
end
|
31
|
+
ys = xs.map do |v|
|
32
|
+
v = case
|
33
|
+
when v >= self.n_colors
|
34
|
+
@over_index
|
35
|
+
when v < 0
|
36
|
+
@under_index
|
37
|
+
else
|
38
|
+
v
|
39
|
+
end
|
40
|
+
@lookup_table[v]
|
41
|
+
end
|
42
|
+
|
43
|
+
if scalar_p
|
44
|
+
ys[0]
|
45
|
+
else
|
46
|
+
ys
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def over_color
|
51
|
+
init_colormap unless @initialized
|
52
|
+
@lookup_table[@over_index]
|
53
|
+
end
|
54
|
+
|
55
|
+
def over_color=(color)
|
56
|
+
@over_color = color
|
57
|
+
update_extreme_colors if @initialized
|
58
|
+
end
|
59
|
+
|
60
|
+
def under_color
|
61
|
+
init_colormap unless @initialized
|
62
|
+
@lookup_table[@under_index]
|
63
|
+
end
|
64
|
+
|
65
|
+
def under_color=(color)
|
66
|
+
@under_color = color
|
67
|
+
update_extreme_colors if @initialized
|
68
|
+
end
|
69
|
+
|
70
|
+
PNG_WIDTH = 512
|
71
|
+
PNG_HEIGHT = 64
|
72
|
+
|
73
|
+
def to_png
|
74
|
+
require "chunky_png"
|
75
|
+
png = ChunkyPNG::Image.new(PNG_WIDTH, PNG_HEIGHT, ChunkyPNG::Color::TRANSPARENT)
|
76
|
+
x = Utils.linspace(0, 1, PNG_WIDTH)
|
77
|
+
(0 ... PNG_WIDTH).each do |i|
|
78
|
+
color = self[x[i].to_f]
|
79
|
+
png_color = ChunkyPNG::Color.rgba(*color.components.map{|v| (v*255).to_i })
|
80
|
+
png.line(i, 0, i, PNG_HEIGHT-1, png_color)
|
81
|
+
end
|
82
|
+
png.to_blob
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_html
|
86
|
+
require "base64"
|
87
|
+
png_blob = to_png
|
88
|
+
png_base64 = Base64.encode64(png_blob)
|
89
|
+
html = %Q[<div style="vertical-align: middle;">] +
|
90
|
+
%Q[<strong>#{self.name}</strong> ] +
|
91
|
+
%Q[</div>] +
|
92
|
+
%Q[<div class="cmap"><img alt="#{self.name} colormap" ] +
|
93
|
+
%Q[title="#{self.name}" style="border: 1px solid #555;" ] +
|
94
|
+
%Q[src="data:image/png;base64,#{png_base64}"></div>] +
|
95
|
+
%Q[<div style="vertical-align: middle; ] +
|
96
|
+
%Q[max-width: #{PNG_WIDTH + 2}px; ] +
|
97
|
+
%Q[display: flex; justify-content: space-between;">] +
|
98
|
+
%Q[<div style="float: left;">] +
|
99
|
+
%Q[#{html_color_block(under_color)} under</div>] +
|
100
|
+
# TODO: bad_color support
|
101
|
+
# %Q[<div style="margin: 0 auto; display: inline-block;">] +
|
102
|
+
# %Q[bad #{html_color_block(bad_color)}</div>] +
|
103
|
+
%Q[<div style="float: right;">] +
|
104
|
+
%Q[over #{html_color_block(over_color)}</div>]
|
105
|
+
["text/html", html]
|
106
|
+
end
|
107
|
+
|
108
|
+
private def html_color_block(color)
|
109
|
+
hex_color = color.to_hex_string
|
110
|
+
html = %Q[<div title="#{hex_color}" style="display: inline-block; ] +
|
111
|
+
%Q[width: 1em; height: 1em; margin: 0; vertical-align: middle; ] +
|
112
|
+
%Q[border: 1px solid #555; background-color: #{hex_color};">] +
|
113
|
+
%Q[</div>]
|
114
|
+
html
|
115
|
+
end
|
116
|
+
|
117
|
+
private def init_colormap
|
118
|
+
raise NotImplementedError
|
119
|
+
end
|
120
|
+
|
121
|
+
private def all_ratio?(ary)
|
122
|
+
ary.all? {|x| x.is_a?(Float) || x.is_a?(Rational) }
|
123
|
+
end
|
124
|
+
|
125
|
+
private def update_extreme_colors
|
126
|
+
@lookup_table[@under_index] = Utils.make_color(@under_color || @lookup_table[0]).to_rgba
|
127
|
+
@lookup_table[@over_index] = Utils.make_color(@over_color || @lookup_table[self.n_colors - 1]).to_rgba
|
128
|
+
@lookup_table[@bad_index] = Utils.make_color(@bad_color).to_rgba
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Colors
|
2
|
+
class LinearSegmentedColormap < Colormap
|
3
|
+
def initialize(name, segmented_data, n_colors: 256, gamma: 1.0)
|
4
|
+
super(name, n_colors)
|
5
|
+
|
6
|
+
@monochrome = false
|
7
|
+
@segmented_data = segmented_data
|
8
|
+
@gamma = gamma
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :segmented_data, :gamma
|
12
|
+
|
13
|
+
def self.new_from_list(name, colors, n_colors: 256, gamma: 1.0)
|
14
|
+
case colors
|
15
|
+
when Enumerable
|
16
|
+
colors = colors.to_a
|
17
|
+
else
|
18
|
+
ary = Array.try_convert(colors)
|
19
|
+
if ary.nil?
|
20
|
+
raise ArgumentError, "colors must be convertible to an array"
|
21
|
+
else
|
22
|
+
colors = ary
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
case colors[0]
|
27
|
+
when Array
|
28
|
+
unless colors.all? {|a| a.length == 2 }
|
29
|
+
raise ArgumentError, "colors array has invalid items"
|
30
|
+
end
|
31
|
+
vals, colors = colors.transpose
|
32
|
+
else
|
33
|
+
vals = Utils.linspace(0r, 1r, colors.length)
|
34
|
+
end
|
35
|
+
|
36
|
+
r, g, b, a = colors.map { |c|
|
37
|
+
Utils.make_color(c).to_rgba.components
|
38
|
+
}.transpose
|
39
|
+
|
40
|
+
segmented_data = {
|
41
|
+
red: [vals, r, r].transpose,
|
42
|
+
green: [vals, g, g].transpose,
|
43
|
+
blue: [vals, b, b].transpose,
|
44
|
+
alpha: [vals, a, a].transpose
|
45
|
+
}
|
46
|
+
|
47
|
+
new(name, segmented_data, n_colors: n_colors, gamma: gamma)
|
48
|
+
end
|
49
|
+
|
50
|
+
def gamma=(val)
|
51
|
+
@gamma = val
|
52
|
+
@initialized = false
|
53
|
+
end
|
54
|
+
|
55
|
+
private def init_colormap
|
56
|
+
red = create_lookup_table(self.n_colors, @segmented_data[:red], @gamma)
|
57
|
+
green = create_lookup_table(self.n_colors, @segmented_data[:green], @gamma)
|
58
|
+
blue = create_lookup_table(self.n_colors, @segmented_data[:blue], @gamma)
|
59
|
+
alpha = if @segmented_data.key?(:alpha)
|
60
|
+
create_lookup_table(self.n_colors, @segmented_data[:alpha], @gamma)
|
61
|
+
end
|
62
|
+
@lookup_table = Array.new(self.n_colors) do |i|
|
63
|
+
Colors::RGBA.new(red[i], green[i], blue[i], alpha ? alpha[i] : 1r)
|
64
|
+
end
|
65
|
+
@initialized = true
|
66
|
+
update_extreme_colors
|
67
|
+
end
|
68
|
+
|
69
|
+
private def create_lookup_table(n, data, gamma=1.0)
|
70
|
+
if data.respond_to?(:call)
|
71
|
+
xind = Utils.linspace(0r, 1r, n).map {|x| x ** gamma }
|
72
|
+
lut = xind.map {|i| data.(i).clamp(0, 1).to_f }
|
73
|
+
return lut
|
74
|
+
end
|
75
|
+
|
76
|
+
ary = Array.try_convert(data)
|
77
|
+
if ary.nil?
|
78
|
+
raise ArgumentError, "data must be convertible to an array"
|
79
|
+
elsif ary.any? {|sub| sub.length != 3 }
|
80
|
+
raise ArgumentError, "data array must consist of 3-length arrays"
|
81
|
+
end
|
82
|
+
|
83
|
+
shape = [ary.length, 3]
|
84
|
+
|
85
|
+
x, y0, y1 = ary.transpose
|
86
|
+
|
87
|
+
if x[0] != 0.0 || x[-1] != 1.0
|
88
|
+
raise ArgumentError,
|
89
|
+
"data mapping points must start with x=0 and end with x=1"
|
90
|
+
end
|
91
|
+
|
92
|
+
unless x.each_cons(2).all? {|a, b| a < b }
|
93
|
+
raise ArgumentError,
|
94
|
+
"data mapping points must have x in increasing order"
|
95
|
+
end
|
96
|
+
|
97
|
+
if n == 1
|
98
|
+
# Use the `y = f(x=1)` value for a 1-element lookup table
|
99
|
+
lut = [y0[-1]]
|
100
|
+
else
|
101
|
+
x.map! {|v| v.to_f * (n - 1) }
|
102
|
+
xind = Utils.linspace(0r, 1r, n).map {|i| (n - 1) * i ** gamma }
|
103
|
+
ind = (0 ... n).map {|i| x.find_index {|v| xind[i] < v } }[1 ... -1]
|
104
|
+
|
105
|
+
distance = ind.map.with_index do |i, j|
|
106
|
+
(xind[j+1] - x[i - 1]) / (x[i] - x[i - 1])
|
107
|
+
end
|
108
|
+
|
109
|
+
lut = [
|
110
|
+
y1[0],
|
111
|
+
*ind.map.with_index {|i, j| distance[j] * (y0[i] - y1[i - 1]) + y1[i - 1] },
|
112
|
+
y0[-1]
|
113
|
+
]
|
114
|
+
end
|
115
|
+
|
116
|
+
return lut.map {|v| v.clamp(0, 1).to_f }
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Colors
|
2
|
+
class ListedColormap < Colormap
|
3
|
+
def initialize(colors, name: :from_list, n_colors: nil)
|
4
|
+
@monochrome = false
|
5
|
+
if n_colors.nil?
|
6
|
+
@colors = Array.try_convert(colors)
|
7
|
+
n_colors = @colors.length
|
8
|
+
else
|
9
|
+
case colors
|
10
|
+
when String, Symbol
|
11
|
+
@colors = Array.new(n_colors) { colors }
|
12
|
+
@monochrome = true
|
13
|
+
when Enumerable
|
14
|
+
@colors = colors.cycle.take(n_colors)
|
15
|
+
@monochrome = @colors.all? {|x| x == @colors[0] }
|
16
|
+
else
|
17
|
+
begin
|
18
|
+
gray = Float(colors)
|
19
|
+
rescue TypeError, ArgumentError
|
20
|
+
raise ArgumentError,
|
21
|
+
"invalid value for `colors` (%p)" % colors
|
22
|
+
else
|
23
|
+
@colors = Array.new(n_colors) { gray }
|
24
|
+
end
|
25
|
+
@monochrome = true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@colors.freeze
|
29
|
+
|
30
|
+
super(name, n_colors)
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :colors
|
34
|
+
|
35
|
+
private def init_colormap
|
36
|
+
@lookup_table = self.colors.map {|color| Utils.make_color(color).to_rgba }
|
37
|
+
@initialized = true
|
38
|
+
update_extreme_colors
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/colors/utils.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Colors
|
2
|
+
module Utils
|
3
|
+
module_function def linspace(x0, x1, n)
|
4
|
+
Array.new(n) { |i|
|
5
|
+
x0 + i*(x1 - x0)/(n-1r)
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
module_function def make_color(value)
|
10
|
+
case value
|
11
|
+
when Colors::AbstractColor
|
12
|
+
value
|
13
|
+
else
|
14
|
+
Colors[value]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/colors/version.rb
CHANGED
@@ -0,0 +1,119 @@
|
|
1
|
+
class ColorsLinearSegmentedColormapTest < Test::Unit::TestCase
|
2
|
+
include TestHelper
|
3
|
+
|
4
|
+
sub_test_case("#[]") do
|
5
|
+
def setup
|
6
|
+
@cm = Colors::LinearSegmentedColormap.new_from_list(:triple_colors, [:red, :green, :blue], n_colors: 11)
|
7
|
+
@cm.under_color = :black
|
8
|
+
@cm.over_color = :white
|
9
|
+
end
|
10
|
+
|
11
|
+
sub_test_case("with an integer") do
|
12
|
+
data do
|
13
|
+
expected = [
|
14
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
15
|
+
Colors::RGBA.new(0r, 128/255r, 0r, 1r),
|
16
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
17
|
+
Colors::RGBA.new(1r, 1r, 1r, 1r),
|
18
|
+
Colors::RGBA.new(0r, 0r, 0r, 1r),
|
19
|
+
]
|
20
|
+
indices = [0, 5, 10, 11, -1]
|
21
|
+
indices.zip(expected).map { |i, c|
|
22
|
+
["cmap[#{i}]", {i: i, expected_color: c}]
|
23
|
+
}.to_h
|
24
|
+
end
|
25
|
+
def test_aref(data)
|
26
|
+
i, expected = data.values_at(:i, :expected_color)
|
27
|
+
assert_near(expected, @cm[i])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
sub_test_case("with an array of integers") do
|
32
|
+
def test_aref
|
33
|
+
indices = [0, 5, 10, 11, -1]
|
34
|
+
assert_equal(indices.map {|i| @cm[i] },
|
35
|
+
@cm[indices])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
sub_test_case("with a float") do
|
40
|
+
data do
|
41
|
+
expected = [
|
42
|
+
Colors::RGBA.new(0.6r, 0.20078431372549022r, 0.0r, 1r),
|
43
|
+
Colors::RGBA.new(0.19999999999999996r, 0.40156862745098043r, 0.0r, 1r),
|
44
|
+
Colors::RGBA.new(0.0r, 0.4015686274509803r, 0.20000000000000018r, 1r),
|
45
|
+
Colors::RGBA.new(0.0r, 0.20078431372549022r, 0.6r, 1r),
|
46
|
+
Colors::RGBA.new(1r, 1r, 1r, 1r),
|
47
|
+
Colors::RGBA.new(0r, 0r, 0r, 1r),
|
48
|
+
]
|
49
|
+
indices = [0.2, 0.4, 0.6, 0.8, 1.2, -0.2]
|
50
|
+
indices.zip(expected).map { |i, c|
|
51
|
+
["cmap[#{i}]", {i: i, expected_color: c}]
|
52
|
+
}.to_h
|
53
|
+
end
|
54
|
+
def test_aref(data)
|
55
|
+
i, expected = data.values_at(:i, :expected_color)
|
56
|
+
assert_near(expected, @cm[i])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
sub_test_case("with an array of floats") do
|
61
|
+
def test_aref
|
62
|
+
indices = [0.2, 0.4, 0.6, 0.8, 1.2, -0.2]
|
63
|
+
assert_equal(indices.map {|i| @cm[i] },
|
64
|
+
@cm[indices])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_over_color
|
70
|
+
cm = Colors::LinearSegmentedColormap.new_from_list(:blue_and_red, [:blue, :red])
|
71
|
+
|
72
|
+
before = cm[[0, 255, 256]]
|
73
|
+
cm.over_color = :black
|
74
|
+
after = cm[[0, 255, 256]]
|
75
|
+
|
76
|
+
assert_equal([
|
77
|
+
[
|
78
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
79
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
80
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
81
|
+
],
|
82
|
+
[
|
83
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
84
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
85
|
+
Colors::RGBA.new(0r, 0r, 0r, 1r),
|
86
|
+
]
|
87
|
+
],
|
88
|
+
[
|
89
|
+
before,
|
90
|
+
after
|
91
|
+
])
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_under_color
|
95
|
+
cm = Colors::LinearSegmentedColormap.new_from_list(:blue_and_red, [:blue, :red])
|
96
|
+
|
97
|
+
before = cm[[0, 255, -1]]
|
98
|
+
cm.under_color = :black
|
99
|
+
after = cm[[0, 255, -1]]
|
100
|
+
|
101
|
+
assert_equal([
|
102
|
+
[
|
103
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
104
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
105
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
106
|
+
],
|
107
|
+
[
|
108
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
109
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
110
|
+
Colors::RGBA.new(0r, 0r, 0r, 1r),
|
111
|
+
]
|
112
|
+
],
|
113
|
+
[
|
114
|
+
before,
|
115
|
+
after
|
116
|
+
])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
@@ -0,0 +1,115 @@
|
|
1
|
+
class ColorsListedColormapTest < Test::Unit::TestCase
|
2
|
+
include TestHelper
|
3
|
+
|
4
|
+
sub_test_case("#[]") do
|
5
|
+
def setup
|
6
|
+
@cm = Colors::ListedColormap.new([:red, :green, :blue])
|
7
|
+
@cm.under_color = :black
|
8
|
+
@cm.over_color = :white
|
9
|
+
end
|
10
|
+
|
11
|
+
sub_test_case("with an integer") do
|
12
|
+
def test_aref
|
13
|
+
assert_equal([
|
14
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
15
|
+
Colors::RGBA.new(0r, 128/255r, 0r, 1r),
|
16
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
17
|
+
Colors::RGBA.new(1r, 1r, 1r, 1r),
|
18
|
+
Colors::RGBA.new(0r, 0r, 0r, 1r),
|
19
|
+
],
|
20
|
+
[
|
21
|
+
@cm[0],
|
22
|
+
@cm[1],
|
23
|
+
@cm[2],
|
24
|
+
@cm[3],
|
25
|
+
@cm[-1],
|
26
|
+
])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
sub_test_case("with an array of integers") do
|
31
|
+
def test_aref
|
32
|
+
indices = [0, 1, 2, 3, -1]
|
33
|
+
assert_equal(indices.map {|i| @cm[i] },
|
34
|
+
@cm[indices])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
sub_test_case("with a float") do
|
39
|
+
def test_aref
|
40
|
+
assert_equal([
|
41
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
42
|
+
Colors::RGBA.new(0r, 128/255r, 0r, 1r),
|
43
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
44
|
+
Colors::RGBA.new(1r, 1r, 1r, 1r),
|
45
|
+
Colors::RGBA.new(0r, 0r, 0r, 1r),
|
46
|
+
],
|
47
|
+
[
|
48
|
+
@cm[0.1],
|
49
|
+
@cm[0.5],
|
50
|
+
@cm[0.8],
|
51
|
+
@cm[1.1],
|
52
|
+
@cm[-0.1]
|
53
|
+
])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
sub_test_case("with an array of floats") do
|
58
|
+
def test_aref
|
59
|
+
indices = [0.1, 0.5, 0.8, 1.1, -0.1]
|
60
|
+
assert_equal(indices.map {|i| @cm[i] },
|
61
|
+
@cm[indices])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_over_color
|
67
|
+
cm = Colors::ListedColormap.new([:blue, :red])
|
68
|
+
|
69
|
+
before = cm[[0, 1, 2]]
|
70
|
+
cm.over_color = :black
|
71
|
+
after = cm[[0, 1, 2]]
|
72
|
+
|
73
|
+
assert_equal([
|
74
|
+
[
|
75
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
76
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
77
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
78
|
+
],
|
79
|
+
[
|
80
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
81
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
82
|
+
Colors::RGBA.new(0r, 0r, 0r, 1r),
|
83
|
+
]
|
84
|
+
],
|
85
|
+
[
|
86
|
+
before,
|
87
|
+
after
|
88
|
+
])
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_under_color
|
92
|
+
cm = Colors::ListedColormap.new([:blue, :red])
|
93
|
+
|
94
|
+
before = cm[[0, 1, -1]]
|
95
|
+
cm.under_color = :black
|
96
|
+
after = cm[[0, 1, -1]]
|
97
|
+
|
98
|
+
assert_equal([
|
99
|
+
[
|
100
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
101
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
102
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
103
|
+
],
|
104
|
+
[
|
105
|
+
Colors::RGBA.new(0r, 0r, 1r, 1r),
|
106
|
+
Colors::RGBA.new(1r, 0r, 0r, 1r),
|
107
|
+
Colors::RGBA.new(0r, 0r, 0r, 1r),
|
108
|
+
]
|
109
|
+
],
|
110
|
+
[
|
111
|
+
before,
|
112
|
+
after
|
113
|
+
])
|
114
|
+
end
|
115
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: red-colors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenta Murata
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-06-
|
11
|
+
date: 2021-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: matrix
|
@@ -110,14 +110,18 @@ files:
|
|
110
110
|
- lib/colors/abstract_color.rb
|
111
111
|
- lib/colors/alpha_component.rb
|
112
112
|
- lib/colors/color_data.rb
|
113
|
+
- lib/colors/colormap.rb
|
113
114
|
- lib/colors/convert.rb
|
114
115
|
- lib/colors/helper.rb
|
115
116
|
- lib/colors/hsl.rb
|
116
117
|
- lib/colors/hsla.rb
|
117
118
|
- lib/colors/husl.rb
|
119
|
+
- lib/colors/linear_segmented_colormap.rb
|
120
|
+
- lib/colors/listed_colormap.rb
|
118
121
|
- lib/colors/named_colors.rb
|
119
122
|
- lib/colors/rgb.rb
|
120
123
|
- lib/colors/rgba.rb
|
124
|
+
- lib/colors/utils.rb
|
121
125
|
- lib/colors/version.rb
|
122
126
|
- lib/colors/xterm256.rb
|
123
127
|
- lib/colors/xyy.rb
|
@@ -128,6 +132,8 @@ files:
|
|
128
132
|
- test/test-hsl.rb
|
129
133
|
- test/test-hsla.rb
|
130
134
|
- test/test-husl.rb
|
135
|
+
- test/test-linear-segmented-colormap.rb
|
136
|
+
- test/test-listed-colormap.rb
|
131
137
|
- test/test-named-color.rb
|
132
138
|
- test/test-rgb.rb
|
133
139
|
- test/test-rgba.rb
|
@@ -163,6 +169,8 @@ test_files:
|
|
163
169
|
- test/test-hsl.rb
|
164
170
|
- test/test-hsla.rb
|
165
171
|
- test/test-husl.rb
|
172
|
+
- test/test-linear-segmented-colormap.rb
|
173
|
+
- test/test-listed-colormap.rb
|
166
174
|
- test/test-named-color.rb
|
167
175
|
- test/test-rgb.rb
|
168
176
|
- test/test-rgba.rb
|