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

后端 未结 1 1910
时光取名叫无心
时光取名叫无心 2021-02-04 09:14

I want to plot a true/false or active/deactive binary data similar to the following picture: \"Tru

1条回答
  •  囚心锁ツ
    2021-02-04 09:51

    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.

    0 讨论(0)
提交回复
热议问题