亮度图(或图像),其中行对应于不同长度的数组

Brightness plot (or image) with rows corresponding to arrays of varying length

我正在使用 Python 和 numpy,scipy,matplotlib。

我有两个包含不同长度数组的列表,为了具体起见,我将调用 x 和 y 并说它们看起来像(实际数组的长度约为 1000 个元素,实际列表有~10s 到 ~100s 数组的顺序):

x = [
    np.array([0, 1, 2, 3, 4]),
    np.array([0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4]),
    np.array([0, 2 ,4])
]
y = [
    np.array([0, 0, 1, 0, 0]),
    np.array([1, 0.75, 0.5, 0.25, 0.0, 0.25, 0.5, 0.75, 1]),
    np.array([0, 1, 0,])
]

每个x数组被排序,每个y数组被对应的x数组排序,所以len(x[i])==len(y[i])总是True并且x[i ][j] 总是对应于 y[i][j]。每个 x 数组的范围都在相同的两个值之间(例如,上例中的 0 和 4)。

我想画图或保存图像(如果可能的话,我想知道如何同时做),其中第 i 行是 y[i] 与 x[i],亮度对应于y 值。

例如,在上面的例子中:

我相信如果 Python 或 numpy 有任何拉伸数组函数,我可以很容易地做到这一点,这样我就可以标准化 x 和 y 中所有数组的长度,或者如果 matplotlib 只是有正是这种类型的情节的内置功能。但是我不知道这两个是否存在。

有谁知道如何做这种事情(或者就此而言,这种情节会被称为什么)?

非常感谢您的帮助。如果我的问题不清楚,请告诉我。

---对上述例子的进一步阐述--- 如果我采用将数组拉伸为相同长度的方法,那么上面的最终数组可能看起来像 (after stretching)

x = [
    np.array([0, 0, 1, 1, 2, 3, 3, 4, 4]),
    np.array([0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4]),
    np.array([0,0,0,2,2,2,4,4,4])
]
y = [
    np.array([0, 0, 0, 0, 1, 0, 0, 0, 0]),
    np.array([1, 0.75, 0.5, 0.25,0, 0 .25,0 .5, 0.75, 1]),
    np.array([0, 0, 0, 1, 1, 1, 0, 0, 0])
]

情节或图像看起来会像 y 的图像版本(我不能 post 没有 10 个声誉点的图像)。

一种方法是使用 numpy.repeat,它将一维数组的每个元素重复一定次数。例如:

>>> np.repeat([1,2,3,4], 3)
array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])

我们的想法是找到所有列表长度的最小公倍数,然后对每个列表使用 np.repeat 以使数组 "stretch" 达到共同长度。

更一般地说,您可以使用 scipy.interpolate.interp1d:

对数组的值进行插值,例如线性插值
from scipy.interpolate import interp1d
import numpy as np

x = np.array([0, 1, 2, 3, 4])
y = np.array([0, 0, 1, 0, 0])

f = interp1d(x,y)
print f(np.linspace(0,4,10))

打印:

[ 0.          0.          0.          0.33333333  0.77777778  0.77777778
  0.33333333  0.          0.          0.        ]

您可以将 interp1dkind="nearest" 一起使用。 (使用 "nearest" 将在边界处给出步骤并且看起来像扩展,但您不需要明确地执行它,并且如果您的长度没有按需要完全划分,也可以对您想要的进行合理的近似。)这将给出如下内容:

import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
import matplotlib.cm as cm


x = [
    np.array([0, 1., 2, 3, 4]),
    np.array([0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4]),
    np.array([0, 2., 4])
]
y = [
    np.array([0, 0, 1., 0, 0]),
    np.array([1, 0.75, 0.5, 0.25, .25, 0, .5, 0.75, 1]),
    np.array([0, 1., 0,])
]

N = 30
xd = np.linspace(0, 4, 30)

data = np.zeros((len(x), N), dtype=np.float)
print data.shape

for i in range(len(x)):
    xi, yi = x[i], y[i]
    f = interpolate.interp1d(x[i], y[i], kind="nearest")
    data[i] = f(xd)

fig, ax = plt.subplots()
i = ax.imshow(data, cmap=cm.gray, interpolation='nearest')
#fig.colorbar(i)

plt.show()

因为输出的 x 维度需要是一个整数,所以您需要有一个可以被所有或您的长度整除的数字。这可能是很大的奇数(在本例中为 45,尽管我在上面的示例中使用 30 作为近似值)。一个完全通用的方法是从补丁构建情节,尽管这会更麻烦。