虽然我的解决方案与 Chris 的解决方案类似,但我还将展示如何定义自定义颜色并概括多个叠加层的方法。
对于每个位置,您都会得到a 中的整数和b 中的整数的贡献。由于它们可以是 0 或 1,因此您可以使用二进制描述。通过将b 中的整数移动到第二个位置,即乘以 2,您可以用 2 位表示任意组合,ba,每个列表中的每个整数(每个位置)一个。
Matplotlib 还允许您create your own custom colour map。结合这些方面,您可以达到您所追求的结果。
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
a = np.array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1])
b = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1])
lists = [a, b]
overlap = np.zeros_like(a)
for k, row in enumerate(lists):
overlap += row * 2**k
cmap = mpl.colors.ListedColormap(['white', 'blue', 'red', 'purple'])
bounds = range((2**len(lists))+1)
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
plt.pcolor(overlap.reshape((1, overlap.shape[0])), edgecolor='k', cmap=cmap, norm=norm)
plt.axes().set_aspect('equal')
plt.xticks([])
plt.yticks([])
plt.xlim(0, len(a))
plt.show()
输出:
如果您有 3 个叠加层,则必须按以下顺序提供颜色列表:
000 white
001 colour A
010 colour B
011 colour A+B
100 colour C
101 colour A+C
110 colour B+C
111 colour A+B+C
很遗憾,这必须手动完成。您可以看到颜色名称列表here。如果颜色没有明确的名称,您始终可以通过字符串中的十六进制值来描述它,例如'#RRGGBB',其中RR 将是红色通道的十六进制值等。所以,而不是@ 987654337@你可以说'#FFFFFF'(字母也可以小写)。
代码注释:
bounds 是数字列表[0, 1, 2, 3, 4]。这意味着从 0 到 1 但不包括 1 的任何值都将被映射到白色,在 1 和 2 之间的任何值都将映射到蓝色等。如果我们有 k 叠加层,我们需要 2**k + 1 边界编号。
我选择用pcolor() 表示数据,因为它具有edgecolor 选项,可以更好地可视化相同颜色的运行。但是,该函数需要一个二维数组作为输入,因此我必须将overlap 数组从大小(29,) 重塑为(1, 29)。不过一般来说,即使 a 和 b 是二维数组,这段代码也可以工作,在这种情况下,您将跳过任何整形。
在本节中,我简要讨论了我考虑过的其他方法,但考虑到 OP 的范围,我发现它们缺乏或不必要的复杂。
Alpha 混合(透明度)
可以为第一个列表创建一行白色-蓝色,然后在其上堆叠另一行白色-红色。理论上,白白就是白,白蓝就是蓝,白红就是红,蓝红就是紫。然而,由于每一行都是半透明的,红色看起来像粉红色和蓝色,白色的层被“稀释”成浅蓝色。这种效果在多层的情况下会更加明显,但至少颜色的组合会在没有任何手动定义的情况下出现。
这种方法的一个优点是它不仅支持任何单个叠加层的 1 或 0,还支持介于两者之间的任何渐变。
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
a = np.array([0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1])
b = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1])
blue = mpl.colors.LinearSegmentedColormap.from_list('blue', ['white', 'blue'], 256)
red = mpl.colors.LinearSegmentedColormap.from_list('red', ['white', 'red'], 256)
plt.pcolor(a.reshape((1, a.shape[0])), cmap=blue, edgecolor='k', alpha=1.0)
plt.pcolor(b.reshape((1, b.shape[0])), cmap=red, edgecolor='k', alpha=0.5)
plt.axes().set_aspect('equal')
plt.xticks([])
plt.yticks([])
plt.xlim(0, len(a))
plt.show()
输出:
RGB 混合
如果将叠加层转换为 RGB 值会怎样?例如,a 中的每个 1 都可以由 [0, 0, 255] 三元组表示。通过混合每个叠加层的 RGB 值,我们可以获得每个位置的最终 RGB 值,然后我们可以使用 RGB 颜色图进行绘制。但是,这不像simple 那样sounds。