Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplot: How to plot true/false or active/deactive data?

I want to plot a true/false or active/deactive binary data similar to the following picture: True/False Plot

The horizontal axis is time and the vertical axis is some entities(Here some sensors) which is active(white) or deactive(black). How can I plot such a graphs using pyplot.

I searched to find the name of these graphs but I couldn't find it.

like image 309
Hadi Avatar asked Aug 24 '14 08:08

Hadi


1 Answers

What you are looking for is imshow:

import matplotlib.pyplot as plt
import numpy as np

# get some data with true @ probability 80 %
data = np.random.random((20, 500)) > .2

fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(data, aspect='auto', cmap=plt.cm.gray, interpolation='nearest')

Then you will just have to get the Y labels from somewhere.

enter image description here

It seems that the image in your question has some interpolation in the image. Let us set a few more things:

import matplotlib.pyplot as plt
import numpy as np

# create a bit more realistic-looking data
# - looks complicated, but just has a constant switch-off and switch-on probabilities
#   per column
# - the result is a 20 x 500 array of booleans
p_switchon = 0.02
p_switchoff = 0.05
data = np.empty((20,500), dtype='bool')
data[:,0] = np.random.random(20) < .2
for c in range(1, 500):
    r = np.random.random(20)
    data[data[:,c-1],c] = (r > p_switchoff)[data[:,c-1]]
    data[-data[:,c-1],c] = (r < p_switchon)[-data[:,c-1]]

# create some labels
labels = [ "label_{0:d}".format(i) for i in range(20) ]

# this is the real plotting part
fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(data, aspect='auto', cmap=plt.cm.gray)
ax.set_yticks(np.arange(len(labels)))
ax.set_yticklabels(labels)

creates enter image description here

However, the interpolation is not necessarily a good thing here. To make the different rows easier to separate, one might use colors:

import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np

# create a bit more realistic-looking data
# - looks complicated, but just has a constant switch-off and switch-on probabilities
#   per column
# - the result is a 20 x 500 array of booleans
p_switchon = 0.02
p_switchoff = 0.05
data = np.empty((20,500), dtype='bool')
data[:,0] = np.random.random(20) < .2
for c in range(1, 500):
    r = np.random.random(20)
    data[data[:,c-1],c] = (r > p_switchoff)[data[:,c-1]]
    data[-data[:,c-1],c] = (r < p_switchon)[-data[:,c-1]]

# create some labels
labels = [ "label_{0:d}".format(i) for i in range(20) ]

# create a color map with random colors
colmap = matplotlib.colors.ListedColormap(np.random.random((21,3)))
colmap.colors[0] = [0,0,0]

# create some colorful data:
data_color = (1 + np.arange(data.shape[0]))[:, None] * data

# this is the real plotting part
fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(data_color, aspect='auto', cmap=colmap, interpolation='nearest')
ax.set_yticks(np.arange(len(labels)))
ax.set_yticklabels(labels)

creates

enter image description here

Of course, you will want to use something less strange as the coloring scheme, but that is really up to your artistic views. Here the trick is that all True elements on row n have value n+1 and, and all False elements are 0 in data_color. This makes it possible to create a color map. Naturally, if you want a cyclic color map with two or three colors, just use the modulus of data_color in imshow by, e.g. data_color % 3.

like image 96
DrV Avatar answered Oct 21 '22 02:10

DrV