O.r*_*rka 6 python user-interface color-scheme colors matplotlib
我正在尝试围绕 2 种颜色构建一个调色板:蓝绿色和玫瑰色
我发现这个网站:https://learnui.design/tools/data-color-picker.html#palette
哪些可以做什么,我一直在寻找的一半,所以我想尝试使用要做到这一点在Python matplotlib,seaborn,palettable,和/或colorsys。
有没有办法在渐变中插入一系列颜色的下一个颜色?
例如,从我给的网站start_color和end_color. 它给了我 6 种颜色,从start_color到end_color. 有没有办法做到这一点,但作出end_color的middle_color,并继续梯度?
from palettable.cartocolors.diverging import TealRose_7
import matplotlib as mpl
import seaborn as sns
start_color = "#009392"
end_color = "#d0587e"
# https://learnui.design/tools/data-color-picker.html#palette
colors = ['#009392', '#0091b2', '#2b89c8', '#7c7ac6', '#b366ac', '#d0587e']
sns.palplot(colors)
Run Code Online (Sandbox Code Playgroud)
我想让蓝绿色start_color保持第一种颜色,使玫瑰end_color成为middle_color(在 3 和 4 之间),然后让调色板完成总共 6 种颜色。
我打算尝试获取 RGB 值,然后进行某种类型的建模以确定它会去哪里,但我认为可能有更简单的方法来做到这一点。
dar*_*sky 10
您可以将颜色视为颜色空间中的一个点,该空间通常由三个或四个维度(如 RGB 或 HSL)组成。要在此空间中的两点之间创建线性插值,只需遵循由这两个点创建的线即可。根据颜色空间的不同,您将获得不同的颜色延续。
下面,我使用matplotlib来显示调色板以及colormath您可以通过 安装的转换pip install colormath。这个库使这项工作比其他方式容易得多。
import colormath
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from colormath.color_objects import sRGBColor, HSVColor, LabColor, LCHuvColor, XYZColor, LCHabColor
from colormath.color_conversions import convert_color
def hex_to_rgb_color(hex):
return sRGBColor(*[int(hex[i + 1:i + 3], 16) for i in (0, 2 ,4)], is_upscaled=True)
def plot_color_palette(colors, subplot, title, plt_count):
ax = fig.add_subplot(plt_count, 1, subplot)
for sp in ax.spines: ax.spines[sp].set_visible(False)
for x, color in enumerate(colors):
ax.add_patch(mpl.patches.Rectangle((x, 0), 0.95, 1, facecolor=color))
ax.set_xlim((0, len(colors)))
ax.set_ylim((0, 1))
ax.set_xticks([])
ax.set_yticks([])
ax.set_aspect("equal")
plt.title(title)
def create_palette(start_rgb, end_rgb, n, colorspace):
# convert start and end to a point in the given colorspace
start = convert_color(start_rgb, colorspace).get_value_tuple()
end = convert_color(end_rgb, colorspace).get_value_tuple()
# create a set of n points along start to end
points = list(zip(*[np.linspace(start[i], end[i], n) for i in range(3)]))
# create a color for each point and convert back to rgb
rgb_colors = [convert_color(colorspace(*point), sRGBColor) for point in points]
# finally convert rgb colors back to hex
return [color.get_rgb_hex() for color in rgb_colors]
start_color = "#009392"
end_color = "#d0587e"
number_of_colors = 10
colorspaces = (sRGBColor, HSVColor, LabColor, LCHuvColor, LCHabColor, XYZColor)
start_rgb = hex_to_rgb_color(start_color)
end_rgb = hex_to_rgb_color(end_color)
fig = plt.figure(figsize=(number_of_colors, len(colorspaces)), frameon=False)
for index, colorspace in enumerate(colorspaces):
palette = create_palette(start_rgb, end_rgb, number_of_colors, colorspace)
plot_color_palette(palette, index + 1, colorspace.__name__, len(colorspaces))
plt.subplots_adjust(hspace=1.5)
plt.show()
Run Code Online (Sandbox Code Playgroud)
线性外推的基本思想是简单地扩展由两种颜色定义的向量。这样做的最大问题是当我们遇到色彩空间的“墙壁”时。例如,想想红色从 0 到 255 的颜色空间 RGB。我们的插值线碰到 255 墙后会发生什么?一种颜色不能比红色更红。我认为您可以继续的一种方法是将这条线视为可以从 rgb 空间的墙壁“反弹”或“反射”的光线。
有趣的是,colormath它似乎并不介意它的颜色对象的参数何时超出其限制。它继续创建一个具有无效十六进制值的颜色对象。这有时会在外推期间发生。为了防止这种情况,我们可以限制 RGB 的值:
rgb_colors = np.maximum(np.minimum(rgb, [1, 1, 1]), [0, 0, 0])
Run Code Online (Sandbox Code Playgroud)
或者让它从墙上“反射”回来,可以这么说。
rgb_colors = []
for color in rgb:
c = list(color)
for i in range(3):
if c[i] > 1:
c[i] = 2 - c[i]
if c[i] < 0:
c[i] *= -1
rgb_colors.append(c)
Run Code Online (Sandbox Code Playgroud)
上面的方程应该是不言自明的。当 RGB 通道低于零时,翻转其符号以“反射”零墙,类似地,当它超过 1 时,将其反射回零。以下是使用此方法的一些外推结果:
def create_palette(start_rgb, end_rgb, n, colorspace, extrapolation_length):
# convert start and end to a point in the given colorspace
start = np.array(convert_color(start_rgb, colorspace, observer=2).get_value_tuple())
mid = np.array(convert_color(end_rgb, colorspace, observer=2).get_value_tuple())
# extrapolate the end point
end = start + extrapolation_length * (mid - start)
# create a set of n points along start to end
points = list(zip(*[np.linspace(start[i], end[i], n) for i in range(3)]))
# create a color for each point and convert back to rgb
rgb = [convert_color(colorspace(*point), sRGBColor).get_value_tuple() for point in points]
# rgb_colors = np.maximum(np.minimum(rgb, [1, 1, 1]), [0, 0, 0])
rgb_colors = []
for color in rgb:
c = list(color)
for i in range(3):
if c[i] > 1:
c[i] = 2 - c[i]
if c[i] < 0:
c[i] *= -1
rgb_colors.append(c)
# finally convert rgb colors back to hex
return [sRGBColor(*color).get_rgb_hex() for color in rgb_colors]
start_color = "#009392"
end_color = "#d0587e"
number_of_colors = 11
colorspaces = (sRGBColor, HSVColor, LabColor, LCHuvColor, LCHabColor, XYZColor, LuvColor)
start_rgb = hex_to_rgb_color(start_color)
end_rgb = hex_to_rgb_color(end_color)
fig = plt.figure(figsize=(6, len(colorspaces)), frameon=False)
for index, colorspace in enumerate(colorspaces):
palette = create_palette(start_rgb, end_rgb, number_of_colors, colorspace, extrapolation_length=2)
plot_color_palette(palette, index + 1, colorspace.__name__, len(colorspaces))
plt.subplots_adjust(hspace=1.2)
plt.show()
Run Code Online (Sandbox Code Playgroud)
请注意,因为 Hue 是一个圆形轴,所以在 HSV 或 HSL 等颜色空间中,它会回绕,如果您将最终颜色放在调色板的中间,您很可能会返回到您的起始颜色附近。
看到这些插值在色彩空间中所采用的路径,真是令人着迷。看一看。请注意从墙壁上反弹的效果。
我可能会在某个时候把它变成一个开源项目。