使用比率绘制 RGB 颜色
Plotting RGB colors using ratios
我目前正在从事一个需要将 RGB 颜色绘制为图形的项目。颜色存储在 nx3 数组中,其中 n 是颜色数,3 是 RGB 值。
例如:
colors = [[0.70248465, 0.10704011, 0.00900125], [0.0067905 , 0.27228963, 0.6428365 ], [0.00859376, 0.36948201, 0.18334154], [0.85125032, 0.65469019, 0.04035713]
假设我有一个数组,用于存储第一种颜色的大小比率。
例如:
ratios = [1,1/2,1/3,1/5]
我想做的是绘制这些颜色但保持大小比例。我当前的功能是:
def plot(colors):
plt.imshow([colors])
plt.axis('off')
plt.show()
绘制颜色如下:
而我想要这样的东西:
这应该可以解决问题:
EXPAND_BY = 30
expanded_colors = []
for c, r in zip(colors, ratios):
expanded_colors += [c] * int(EXPAND_BY * r)
colors = expanded_colors
在选择 EXPAND_BY
的值时要小心。比率的最大公分母是正确的,但任何 large-ish 值都应该给出视觉上令人信服的结果。
它是如何工作的?
Imshow
假设它得到的每个 RGB 三元组是一个“像素”。该解决方案只是根据其大小比例重复每个条目(像素)。
对于较大的数据,内存效率可能不是很高,但代码效率很高 - 只有少数额外的行:)
下面的方法使用了ListedColormap
。这些比率乘以某个足够大的因子,四舍五入并用作重复因子。
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
colors = [[0.70248465, 0.10704011, 0.00900125], [0.0067905, 0.27228963, 0.6428365], [0.00859376, 0.36948201, 0.18334154], [0.85125032, 0.65469019, 0.04035713]]
ratios = [1, 1/2, 1/3, 1/5]
ratios_int = (np.array(ratios) * 60).round().astype(int)
plt.imshow(np.repeat(np.arange(len(colors)), ratios_int).reshape(1, -1),
cmap=ListedColormap(colors), # the given list of colors
aspect=ratios_int.sum()/10) # 1:10 aspect ratio for the image
plt.axis('off')
plt.show()
ratio_int
是一个仅包含整数的数组,但其比率与给定的小数比率相似。如果所有的分母都是整数,可以乘以分母的最小公倍数。在示例中,60 用作乘数。一般来说,对于不能表示为小整数之间的比率的分数,足够大的乘数就可以完成这项工作。即使这会在精确比率之间产生微小的差异,这种微小的差异在生成的图像中也不会很明显。
np.arange(len(colors))
给出数组0,1,2,3,...
。 Matplotlib 的颜色映射会将这些映射到 ListedColormap
中的相应颜色。 np.repeat([0,1,2,3], [60,30,20,12])
将重复 0
60
次,1
重复 30
次,等等。因此,这将创建一个数组,其中每个数字重复对应于给定的比率. .reshape(1,-1)
将此一维数组转换为适合 imshow
的二维数组。第一个维度是 1
,第二个维度等于一维数组的长度(-1
表示“根据需要获取尽可能多的内容,使初始数组和重塑后的数组具有相同数量的元素” ).
我目前正在从事一个需要将 RGB 颜色绘制为图形的项目。颜色存储在 nx3 数组中,其中 n 是颜色数,3 是 RGB 值。
例如:
colors = [[0.70248465, 0.10704011, 0.00900125], [0.0067905 , 0.27228963, 0.6428365 ], [0.00859376, 0.36948201, 0.18334154], [0.85125032, 0.65469019, 0.04035713]
假设我有一个数组,用于存储第一种颜色的大小比率。
例如:
ratios = [1,1/2,1/3,1/5]
我想做的是绘制这些颜色但保持大小比例。我当前的功能是:
def plot(colors):
plt.imshow([colors])
plt.axis('off')
plt.show()
绘制颜色如下:
而我想要这样的东西:
这应该可以解决问题:
EXPAND_BY = 30
expanded_colors = []
for c, r in zip(colors, ratios):
expanded_colors += [c] * int(EXPAND_BY * r)
colors = expanded_colors
在选择 EXPAND_BY
的值时要小心。比率的最大公分母是正确的,但任何 large-ish 值都应该给出视觉上令人信服的结果。
它是如何工作的?
Imshow
假设它得到的每个 RGB 三元组是一个“像素”。该解决方案只是根据其大小比例重复每个条目(像素)。
对于较大的数据,内存效率可能不是很高,但代码效率很高 - 只有少数额外的行:)
下面的方法使用了ListedColormap
。这些比率乘以某个足够大的因子,四舍五入并用作重复因子。
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
colors = [[0.70248465, 0.10704011, 0.00900125], [0.0067905, 0.27228963, 0.6428365], [0.00859376, 0.36948201, 0.18334154], [0.85125032, 0.65469019, 0.04035713]]
ratios = [1, 1/2, 1/3, 1/5]
ratios_int = (np.array(ratios) * 60).round().astype(int)
plt.imshow(np.repeat(np.arange(len(colors)), ratios_int).reshape(1, -1),
cmap=ListedColormap(colors), # the given list of colors
aspect=ratios_int.sum()/10) # 1:10 aspect ratio for the image
plt.axis('off')
plt.show()
ratio_int
是一个仅包含整数的数组,但其比率与给定的小数比率相似。如果所有的分母都是整数,可以乘以分母的最小公倍数。在示例中,60 用作乘数。一般来说,对于不能表示为小整数之间的比率的分数,足够大的乘数就可以完成这项工作。即使这会在精确比率之间产生微小的差异,这种微小的差异在生成的图像中也不会很明显。
np.arange(len(colors))
给出数组0,1,2,3,...
。 Matplotlib 的颜色映射会将这些映射到 ListedColormap
中的相应颜色。 np.repeat([0,1,2,3], [60,30,20,12])
将重复 0
60
次,1
重复 30
次,等等。因此,这将创建一个数组,其中每个数字重复对应于给定的比率. .reshape(1,-1)
将此一维数组转换为适合 imshow
的二维数组。第一个维度是 1
,第二个维度等于一维数组的长度(-1
表示“根据需要获取尽可能多的内容,使初始数组和重塑后的数组具有相同数量的元素” ).