Search code examples
pythonnumpymatplotlibscipysparse-matrix

python matplotlib plot sparse matrix pattern


Given a sparse binary matrix A (csr, coo, whatever) I want to make a plot such that I can see the position (i,j) = white in the figure if A(i,j) = 1, and (i,j) = black if A(i,j) = 0;

For a dense numpy array, matshow will do the job. However, the dimension of my sparse matrix (say 100000 x 1000000) is to big to be converted to a dense array. I wonder how could I plot the pattern in my sparse matrix.

Thanks


Solution

  • You can get a nice result using a coo_matrix, plot() and some adjustments:

    import matplotlib.pyplot as plt
    from scipy.sparse import coo_matrix
    
    def plot_coo_matrix(m):
        if not isinstance(m, coo_matrix):
            m = coo_matrix(m)
        fig = plt.figure()
        ax = fig.add_subplot(111, facecolor='black')
        ax.plot(m.col, m.row, 's', color='white', ms=1)
        ax.set_xlim(0, m.shape[1])
        ax.set_ylim(0, m.shape[0])
        ax.set_aspect('equal')
        for spine in ax.spines.values():
            spine.set_visible(False)
        ax.invert_yaxis()
        ax.set_aspect('equal')
        ax.set_xticks([])
        ax.set_yticks([])
        return ax
    

    Note that the y axis is inverted to put the first row at the top of the figure. One example:

    import numpy as np
    from scipy.sparse import coo_matrix
    
    shape = (100000, 100000)
    rows = np.int_(np.round_(shape[0]*np.random.random(1000)))
    cols = np.int_(np.round_(shape[1]*np.random.random(1000)))
    vals = np.ones_like(rows)
    
    m = coo_matrix((vals, (rows, cols)), shape=shape)
    ax = plot_coo_matrix(m)
    ax.figure.show()
    

    enter image description here