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

时间:2015-01-14 05:08:50

标签: python arrays numpy matplotlib variable-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值。

例如,在上面的例子中:

  • 对于整个绘图,x轴将从0变为4(如果我保存图像而不是绘制图,那么我并不担心显然在轴上显示x值,但是我只知道每行的y值对应于从0到4的x值。
  • 第一行的中间五分之一将为白色,其余部分为黑色。
  • 第二排将被划分为八个,中间的行为黑色,两个边缘为白色,其余为灰色阴影。
  • 第3行将被分为三部分,行的中间三分之一为白色,而行的两部分三分之一为黑色。

如果Python或numpy具有任何拉伸数组函数,我确信我可以轻松地做到这一点,这样我就可以规范化x和y中所有数组的长度,或者如果matplotlib只是内置了正是这种类型的情节的功能。但我不知道其中任何一个是否存在。

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

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

---进一步阐述上述例子--- 如果我沿着拉伸阵列的路径全部具有相同的长度,那么上面的最终数组可能看起来像(拉伸后)

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的图像版本(我无法发布没有10个声望点的图像)。

2 个答案:

答案 0 :(得分:1)

您可以将interp1dkind="nearest"一起使用。 (使用“最近”将在边界处给出步骤并看起来像一个扩展,但不需要明确地做,并且如果你的长度没有根据需要精确划分,也可以合理地近似你想要的东西。)这会给出这样的东西:

enter image description here

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作为近似值)。一个完全可以推广的方法是从补丁构建情节,尽管这会更麻烦。

答案 1 :(得分:0)

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

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

我们的想法是找到所有列表长度的最小公倍数,然后在每个列表上使用np.repeat来"延伸"数组到一个共同的长度。

更一般地说,您可以使用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.        ]