カラー パレットとそれらを処理するためのユーティリティを提供する Python モジュールがあります。カラー パレット オブジェクトは単純に から継承listされ、HEX 文字列で指定された色のリストにすぎません。カラー パレット オブジェクトには、それ自体を拡張して、必要な数の色を提供する機能があります。多くの異なるデータセットが表現されているグラフを想像してください。パレットは、各グラフ データセットに固有の色を提供するために必要な範囲まで、色の数を拡張するように要求できます。これは、隣接する色の平均を取り、この新しい平均色を挿入するだけです。
関数はextend_palette機能しますが、パレットを均一に拡張しません。たとえば、パレットは最初は次のようになります。

15 色に拡張してもまだ使用可能です。

30 色に拡張すると、拡張アルゴリズムの問題が明らかになります。新しい色は、色のリストの一端にのみ追加されています:

extend_palette拡張された新しい色がパレット内でより均一に分散されるようにするには、モジュールの機能をどのように変更する必要がありますか?
コードは次のとおりです (関数extend_paletteに特に焦点を当て、実験の便宜のためにその他のコードを示します)。
def clamp(x):
return max(0, min(x, 255))
def RGB_to_HEX(RGB_tuple):
# This function returns a HEX string given an RGB tuple.
r = RGB_tuple[0]
g = RGB_tuple[1]
b = RGB_tuple[2]
return "#{0:02x}{1:02x}{2:02x}".format(clamp(r), clamp(g), clamp(b))
def HEX_to_RGB(HEX_string):
# This function returns an RGB tuple given a HEX string.
HEX = HEX_string.lstrip("#")
HEX_length = len(HEX)
return tuple(
int(HEX[i:i + HEX_length // 3], 16) for i in range(
0,
HEX_length,
HEX_length // 3
)
)
def mean_color(colors_in_HEX):
# This function returns a HEX string that represents the mean color of a
# list of colors represented by HEX strings.
colors_in_RGB = []
for color_in_HEX in colors_in_HEX:
colors_in_RGB.append(HEX_to_RGB(color_in_HEX))
sum_r = 0
sum_g = 0
sum_b = 0
for color_in_RGB in colors_in_RGB:
sum_r += color_in_RGB[0]
sum_g += color_in_RGB[1]
sum_b += color_in_RGB[2]
mean_r = sum_r / len(colors_in_RGB)
mean_g = sum_g / len(colors_in_RGB)
mean_b = sum_b / len(colors_in_RGB)
return RGB_to_HEX((mean_r, mean_g, mean_b))
class Palette(list):
def __init__(
self,
name = None, # string name
description = None, # string description
colors = None, # list of colors
*args
):
super(Palette, self).__init__(*args)
self._name = name
self._description = description
self.extend(colors)
def name(
self
):
return self._name
def set_name(
self,
name = None
):
self._name = name
def description(
self
):
return self._description
def set_description(
self,
description = None
):
self._description = description
def extend_palette(
self,
minimum_number_of_colors_needed = 15
):
colors = extend_palette(
colors = self,
minimum_number_of_colors_needed = minimum_number_of_colors_needed
)
self = colors
def save_image_of_palette(
self,
filename = "palette.png"
):
save_image_of_palette(
colors = self,
filename = filename
)
def extend_palette(
colors = None, # list of HEX string colors
minimum_number_of_colors_needed = 15
):
while len(colors) < minimum_number_of_colors_needed:
for index in range(1, len(colors), 2):
colors.insert(index, mean_color([colors[index - 1], colors[index]]))
return colors
def save_image_of_palette(
colors = None, # list of HEX string colors
filename = "palette.png"
):
import numpy
import Image
scale_x = 200
scale_y = 124
data = numpy.zeros((1, len(colors), 3), dtype = numpy.uint8)
index = -1
for color in colors:
index += 1
color_RGB = HEX_to_RGB(color)
data[0, index] = [color_RGB[0], color_RGB[1], color_RGB[2]]
data = numpy.repeat(data, scale_x, axis=0)
data = numpy.repeat(data, scale_y, axis=1)
image = Image.fromarray(data)
image.save(filename)
# Define color palettes.
palettes = []
palettes.append(Palette(
name = "palette1",
description = "primary colors for white background",
colors = [
"#fc0000",
"#ffae3a",
"#00ac00",
"#6665ec",
"#a9a9a9",
]
))
palettes.append(Palette(
name = "palette2",
description = "ATLAS clarity",
colors = [
"#FEFEFE",
"#AACCFF",
"#649800",
"#9A33CC",
"#EE2200",
]
))
def save_images_of_palettes():
for index, palette in enumerate(palettes):
save_image_of_palette(
colors = palette,
filename = "palette_{index}.png".format(index = index + 1)
)
def access_palette(
name = "palette1"
):
for palette in palettes:
if palette.name() == name:
return palette
return None
