假设我有两个列表:
a=[00000011000000111100001100001]
b=[00000111100000010000001100001]
有没有办法可视化交叉路口? 我的意思是创建一些情节或图片,其中白色背景将为零,来自 [a] 的图片将为红色,来自 [b] 的图片 - 蓝色,以及它们的重叠 - 紫色?
答案 0 :(得分:1)
虽然我的解决方案与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
将是红色通道的十六进制值,等等那么,代替'white'
你可以说'#FFFFFF'
(字母也可以是小写的)。
代码备注:
bounds
是数字[0, 1, 2, 3, 4]
的列表。这意味着从0到1但不包括1的任何值都将映射到白色,1到2之间的任何值都会映射到蓝色等。如果我们有k
叠加,我们需要2**k + 1
个边界号。
我选择用pcolor()
表示数据,因为它具有edgecolor
选项,这样可以更好地显示相同颜色的运行。但是,该函数需要2D数组进行输入,因此我必须将overlap
数组从大小(29,)
重新整形为(1, 29)
。但一般情况下,即使a
和b
是2D数组,此代码也会起作用,在这种情况下,您将跳过任何重新整形。
在本节中,我简要讨论了我考虑过的其他方法,但考虑到OP的范围,我发现这些方法缺乏或不必要复杂。
可以为第一个列表创建一行白蓝色,并在其上叠加另一行白红色。理论上,白色为白色,白色为蓝色,白色为红色,蓝色为红色。然而,由于每行只是半透明的,红色看起来像粉红色和蓝色,白色的层变得稀疏"浅蓝色。对于多个图层,这种效果会更加明显,但至少会出现没有任何手动定义的颜色组合。
这种方法的一个优点是它不仅仅支持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值怎么办?例如,a
中的每个1都可以由[0, 0, 255]
三元组表示。通过混合每个叠加的RGB值,我们可以获得每个位置的最终RGB值,然后我们可以用RGB色彩图绘制。但是,这不是simple sounds。
答案 1 :(得分:0)
我的建议是创建一个包含4个值的列表:
0 = 0两者,1 = 1 in b,2 = 1 in a,3 = 1 in this
您可以通过将第一个列表乘以2并将其添加到第二个列表来完成此操作。这将产生列表c,其值为0-3,基于原始两个列表中1的显示位置。
使用matplotlib生成图表,如下所示:
import matplotlib.pyplot as plt
a = [0,1,0,1,0,0,0,0,1,0,0,0,1,1,1]
b = [0,0,1,0,0,1,1,0,0,0,1,0,1,1,0]
c = []
for i, item in enumerate(a):
c.append(item * 2 + b[i])
x = range(0,len(a))
y = [1] * len(a)
plt.scatter(x, y, c=c, s=500)
plt.show()
您可以打印(c)以显示颜色索引的工作原理:
c = [0,2,1,2,0,1,1,0,2,0,1,0,3,3,2]
在这种情况下 - 蓝色:两个= 0,黄色:a = 1,浅蓝色:b = 1,红色:两个= 1