【问题标题】:How to visualize overlapping data in python?如何在python中可视化重叠数据?
【发布时间】:2016-02-05 12:46:20
【问题描述】:

假设我有两个列表:

a=[00000011000000111100001100001]
b=[00000111100000010000001100001]

有什么方法可以可视化路口吗? 我的意思是创建一些情节或图片,其中白色背景为零,来自 [a] 的那些将是红色,来自 [b] 的那些 - 蓝色,并且它们重叠 -紫罗兰色?

【问题讨论】:

  • 所以你有 a == [83010353356805013505L] 和 b == [674459080744761589761L]?
  • 什么意思? [a] 和 [b] 是二进制字符串。
  • 不,它们是每个包含一个整数的列表。
  • 是的,你是对的。我从 csv 文件中读取它们。
  • 我会问你最后一次回答问题 a 和 b 在你的程序中的样子,然后再决定这是浪费时间。什么是 a 和 b?整数列表,字符串列表?通心粉?

标签: python plot visualization


【解决方案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 将是红色通道的十六进制值等。所以,而不是@ 987654337@你可以说'#FFFFFF'(字母也可以小写)。

代码注释

bounds 是数字列表[0, 1, 2, 3, 4]。这意味着从 0 到 1 但不包括 1 的任何值都将被映射到白色,在 1 和 2 之间的任何值都将映射到蓝色等。如果我们有 k 叠加层,我们需要 2**k + 1 边界编号。

我选择用pcolor() 表示数据,因为它具有edgecolor 选项,可以更好地可视化相同颜色的运行。但是,该函数需要一个二维数组作为输入,因此我必须将overlap 数组从大小(29,) 重塑为(1, 29)。不过一般来说,即使 ab 是二维数组,这段代码也可以工作,在这种情况下,您将跳过任何整形。


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

【讨论】:

  • 非常感谢 Reti43!这正是我所需要的
【解决方案2】:

我的建议是创建一个包含 4 个值的列表:

0 = 0 在两者中,1 = 1 在 b 中,2 = 1 在 a 中,3 = 1 在两者中

您可以通过将第一个列表乘以 2 并将其添加到第二个列表来完成此操作。这将根据 1 在原始两个列表中的显示位置生成列表 c,其值为 0-3。

使用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()

您可以 print(c) 显示颜色索引的工作原理:

c = [0, 2, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 3, 3, 2]

在这种情况下 - 蓝色:both=0,黄色:a=1,浅蓝色:b=1,红色:both=1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 2018-07-16
    相关资源
    最近更新 更多