如何在python中可视化重叠数据?

时间:2016-02-05 12:46:21

标签: python plot visualization

假设我有两个列表:

a=[00000011000000111100001100001]
b=[00000111100000010000001100001]

有没有办法可视化交叉路口? 我的意思是创建一些情节或图片,其中白色背景将为零,来自 [a] 的图片将为红色,来自 [b] 的图片 - 蓝色,以及它们的重叠 - 紫色?

2 个答案:

答案 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()

输出:

enter image description here

如果您有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)。但一般情况下,即使ab是2D数组,此代码也会起作用,在这种情况下,您将跳过任何重新整形。

在本节中,我简要讨论了我考虑过的其他方法,但考虑到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()

输出:enter image description here

RGB混合

如果将叠加层转换为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

blue: 0, yellow: a=1, light blue: b=1, red: both = 1