亮度图(或图像),其中行对应于不同长度的数组
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 值。
例如,在上面的例子中:
- 对于整个绘图,x 轴将从 0 变为 4(如果我保存图像而不是绘制绘图,那么我并不担心明确地在轴上显示 x 值,但是我只知道每一行的 y 值对应于从 0 到 4 的 x 值。
- 第一行的中间五分之一为白色,其余为黑色。
- 第 2 行将分成八份,中间为黑色,两边为白色,其余部分为不同深浅的灰色。
- 第 3 行将被分成三份,中间三分之一的行是白色的,两边的三分之一是黑色的。
我相信如果 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. ]
您可以将 interp1d
与 kind="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 作为近似值)。一个完全通用的方法是从补丁构建情节,尽管这会更麻烦。
我正在使用 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 值。
- 第一行的中间五分之一为白色,其余为黑色。
- 第 2 行将分成八份,中间为黑色,两边为白色,其余部分为不同深浅的灰色。
- 第 3 行将被分成三份,中间三分之一的行是白色的,两边的三分之一是黑色的。
我相信如果 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. ]
您可以将 interp1d
与 kind="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 作为近似值)。一个完全通用的方法是从补丁构建情节,尽管这会更麻烦。