Update data on matplotlib

Viewed 110

I want to update data on a matplolib plot, thus I have patched code from several examples. Just for illustration purpose, I have two different matrix data which will be plotted in two different subplots alternately. This is the code:

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

matrix1 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
matrix2 = np.array([[2,3,4,5],[6,7,8,9],[10,11,12,13]])

plt.ion()

fig = plt.figure()
ax1 = fig.add_subplot(222)
ax2 = fig.add_subplot(221)

def update(mat1, mat2):

    ax1.plot(mat1.T, 'ro', color='red')
    ax2.plot(mat2.T, 'ro', color='blue')

    fig.canvas.draw()
    fig.canvas.flush_events()

    time.sleep(1)
    
    ax1.plot(mat2.T, 'ro', color='blue')
    ax2.plot(mat1.T, 'ro', color='red')

    fig.canvas.draw()
    fig.canvas.flush_events()

    time.sleep(1)

for i in range(10):
    update(matrix1, matrix2)

which obviously doesn't work. As it is illustrated below, data of matrix1 (red) and matrix2 (blue) should appear not simultaneously in each subplot, but one matrix an each subplot and reverse position after each second.

enter image description here

Any suggestions would be appreciated.

P.S. I know that there are similar questions which I tried to consult, but with no luck.

2 Answers

matplotlib provides an animation library. It is better to use it since the animation event loop has better error handling, e.g. when you close the plot figure when run from a script.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

matrix1 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
matrix2 = np.array([[2,3,4,5],[6,7,8,9],[10,11,12,13]])
matrices = [matrix1.T, matrix2.T]

fig, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
lines1 = ax1.plot(matrices[0], 'ro', color='red')
lines2 = ax2.plot(matrices[1], 'ro', color='blue')

def update(frame):
    matrices.reverse()
    for index, l1, l2 in zip(range(3), lines1, lines2):
        l1.set_data(range(4), matrices[0][:, index])
        l2.set_data(range(4), matrices[1][:, index])

ani = FuncAnimation(fig, update, frames=range(10), interval=1000)
plt.show()

In order to use FuncAnimation(), you keep track of the Line2D object(s) returned by ax.plot(), in this case lines1 and lines2 are lists of Line2D objects (6 in total since each matrix has three rows). Then in the update() function, you can .set_data() or do whatever you need to change the data how you like. You can check out the documentation for Line2D on how to change the plotted data's color with line.set_color() and more.

Try with this

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

from numpy.core.shape_base import block

matrix1 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
matrix2 = np.array([[2,3,4,5],[6,7,8,9],[10,11,12,13]])

plt.ion()

fig = plt.figure()
ax1 = fig.add_subplot(222)
ax2 = fig.add_subplot(221)



def update(mat1, mat2):

    ax1.plot(mat1.T, 'ro', color='red')
    ax2.plot(mat2.T, 'ro', color='blue')
    plt.show()
    plt.pause(1)
    ax1.clear()
    ax2.clear()
    
    ax1.plot(mat2.T, 'ro', color='blue')
    ax2.plot(mat1.T, 'ro', color='red')
    plt.show()
    plt.pause(1)

    ax1.clear()
    ax2.clear()

for i in range(10):
    update(matrix1, matrix2)
Related