Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic graph using matplotlib getting slower after a while [duplicate]

I am trying to make a dynamic grid using matplotlib. However, after running for only around 10 interations, the time step seems to be getting longer and longer even though I have set it to a fixed number (0.1 sec in the code). It gets unacceptably slow (around 3 seconds per change) after about 70 iterations. Here's an example of the code:

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


    map=[[0,0,0],[0,0,0],[0,0,0]]

    plt.ion()
    fig, ax = plt.subplots(1, 1, tight_layout=True)
    color = ['white', 'black', 'red']
    my_cmap = colors.ListedColormap(color)
    # draw the grid
    for x in range(len(map)):
            ax.axhline(x, lw=2, color='k')
        ax.axvline(x, lw=2, color='k')
    ax.axis('off')
    plt.draw()

    for i in range(0,100):
        x = np.random.randint(0,3)
        y = np.random.randint(0,3)

        map[x][y]+=1
        map[x][y]*=-1
        # draw the boxes
        ax.imshow(map, interpolation='none', cmap=my_cmap, extent=[0, len(map), 0, len(map)])
        # turn off the axis labels
        plt.pause(0.1)

I am using python3.7. Is there somewhere wrong with how I draw the graph? Or is there a better way to draw it so that the changing does not slow down after some iterations? Thanks a lot for helping!

like image 265
cxc Avatar asked Sep 18 '25 19:09

cxc


1 Answers

EDIT: just found this answer which basically does exactly the same.

Instead of calling imshow repeatedly, it is more efficient to update the data within the plot. I would add a variable (img below) to store a reference to the displayed image and use set_data to change the pixels:

img = None
for i in range(0,100):
    x = np.random.randint(0,3)
    y = np.random.randint(0,3)

    map[x][y]+=1
    map[x][y]*=-1

    # draw the boxes
    if img is None:
        img = ax.imshow(map, interpolation='none', cmap=my_cmap, 
                        extent=[0, len(map), 0, len(map)])
    else:
        img.set_data(map)
    # turn off the axis labels
    plt.pause(0.1)
like image 91
SamProell Avatar answered Sep 21 '25 12:09

SamProell