在Python中绘制二进制数据

3
我有一些数据,看起来像这样: data = [1,2,4,5,9](递增整数的随机模式)
我想在一个二进制水平线上绘制它,以便对于指定在 data 中的每个x值,y=1,否则为零。
我有几个不同的 data 数组,我想要堆叠,类似于这种风格(这是CCD时钟数据,但绘图格式看起来很理想)

binary plot

我想在我的数据数组中创建一个值为1的列表,但是如何指定数组之外的所有内容的零值?
谢谢
2个回答

5
你说得很对。你可以在数据中指定的任何位置创建一个包含1的列表,并在其他位置包含0。这可以通过使用列表推导式来轻松完成。
def binary_data(data):
    return [1 if x in data else 0 for x in range(data[-1] + 1)]

这将会像这样运作:
>>> data = [1, 2, 4, 5, 9]
>>> bindata = binary_data(data)
>>> bindata
[0, 1, 1, 0, 1, 1, 0, 0, 0, 1]

现在你需要做的就是绘制它... 或者更好的是 步进,因为它是二进制数据,step() 看起来更好:
import numpy as np
from matplotlib.pyplot import step, show

def binary_data(data):
    return [1 if x in data else 0 for x in range(data[-1] + 1)]

data = [1, 2, 4, 5, 9]
bindata = binary_data(data)
xaxis = np.arange(0, data[-1] + 1)
yaxis = np.array(bindata)
step(xaxis, yaxis)
show()

为了在同一图形上叠加多个数据数组,您可以这样调整binary_data()函数:
def binary_data(data, yshift=0):
    return [yshift+1 if x in data else yshift for x in range(data[-1] + 1)]

现在您可以设置yshift参数来在y轴上移动数据数组。例如:

>>> data = [1, 2, 4, 5, 9]
>>> bindata1 = binary_data(data)
>>> bindata1
[0, 1, 1, 0, 1, 1, 0, 0, 0, 1]
>>> bindata2 = binary_data(data, 2)
>>> bindata2
[2, 3, 3, 2, 3, 3, 2, 2, 2, 3]

假设你有要叠加绘制的data1data2data3,你可以这样实现:

import numpy as np
from matplotlib.pyplot import step, show

def binary_data(data, yshift=0):
    return [yshift+1 if x in data else yshift for x in range(data[-1] + 1)]

data1 = [1, 2, 4, 5, 9]
bindata1 = binary_data(data1)
x1 = np.arange(0, data1[-1] + 1)
y1 = np.array(bindata1)

data2 = [1, 4, 9]
bindata2 = binary_data(data2, 2)
x2 = np.arange(0, data2[-1] + 1)
y2 = np.array(bindata2)

data3 = [1, 2, 8, 9]
bindata3 = binary_data(data3, 4)
x3 = np.arange(0, data3[-1] + 1)
y3 = np.array(bindata3)

step(x1, y1, x2, y2, x3, y3)
show()

您可以轻松地编辑它使其适用于任意数量的数据数组:

data = [ [1, 2, 4, 5, 9],
         [1, 4, 9],
         [1, 2, 8, 9] ]

for shift, d in enumerate(data):
    bindata = binary_data(d, 2 * shift)
    x = np.arange(0, d[-1] + 1)
    y = np.array(bindata)
    step(x, y)

show()


最后,如果你正在处理长度不同的数据数组(比如[1,2][15,16]),而且你不想看到图形在图像中间消失,那么你可以再次调整binary_data()函数,将其范围强制设置为数据的最大范围。

import numpy as np
from matplotlib.pyplot import step, show

def binary_data(data, limit, yshift=0):
    return [yshift+1 if x in data else yshift for x in range(limit)]


data = [  [1, 2, 4, 5, 9, 12, 13, 14],
          [1, 4, 10, 11,  20, 21, 22],
          [1, 2, 3, 4, 15, 16, 17, 18] ]

# find out the longest data to plot
limit = max( [ x[-1] + 1 for x in data] )
x = np.arange(0, limit)

for shift, d in enumerate(data):
    bindata = binary_data(d, limit, 2 * shift)
    y = np.array(bindata)
    step(x, y)

show()


编辑:如@ImportanceOfBeingErnest所建议的,如果你想在不定义自己的binary_data()函数的情况下执行databindata的转换,你可以使用numpy.zeros_like()。只需在堆叠它们时更加注意:

import numpy as np
from matplotlib.pyplot import step, show

data = [  [1, 2, 4, 5, 9, 12, 13, 14],
          [1, 4, 10, 11,  20, 21, 22],
          [1, 2, 3, 4, 15, 16, 17, 18] ]

# find out the longest data to plot
limit = max( [ x[-1] + 1 for x in data] )
x = np.arange(0, limit)

for shift, d in enumerate(data):
    y = np.zeros_like(x)
    y[d] = 1
    # don't forget to shift
    y += 2*shift
    step(x, y)

show()

2
你可以创建一个全为零的数组,并将数据中那些元素赋值为1
import numpy as np

data = [1,2,4,5,9]
t = np.arange(0,data[-1]+1)
x = np.zeros_like(t)
x[data] = 1

您可以使用step函数绘制它。
import matplotlib.pyplot as plt
plt.step(t,x, where="post")
plt.show()

这里输入图片描述

或者使用 where = "pre",具体取决于如何解释您的数据。

这里输入图片描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接