Colorbar update using blitting | python matplotlib

Viewed 80

I am making a gui to manipulate some custom laser hardware. Via this gui I can grab data from imaging experiments (scan in some rectangular area). During experiment, I fill a matrix previously initialized by zeros, with real data. The matrix has a shape, say, 500x500. Each step in the loop, I get a new value. And I need to visualize my matrix in real time.

Recently, I used matplotlib's imshow and fig.canvas.draw() function to fully redraw an image on each step. It worked just perfect except the speed. It took about 100 ms to plot one image and it is not good for me as I have to plot thousands of images.

I decided to speed up the rendering process using blitting. It does a perfect job, but my colorbar stopped updating each iteration. Each iteration I set new vmin and vmax values, but colorbar isn't being updated. I suggest it is due to restore a background function fig.canvas.restore_region(bg). I tried different ways to solve this problem for many hours, but I don't succeed. I found a solution for animate function, but I want to redraw image manually in a loop.

Below is my "model" code. In a loop I want to see updating both the plot and the colorbar but colorbar will update only once at the end. Do not understand why.

import matplotlib.pyplot as plt
import numpy as np
import time
from mpl_toolkits.axes_grid1 import make_axes_locatable

fig, ax = plt.subplots()

ax.set_axis_off()
z = np.random.randint(0, 100, size = (500, 500))
line = ax.imshow(z, cmap="jet", extent=[0,100,0,100], interpolation="none", animated=True)

div = make_axes_locatable(ax)
cax = div.append_axes('right', '5%', '5%')
cbar = fig.colorbar(line, cax=cax)

plt.show(block=False)
plt.pause(0.05)

bg = fig.canvas.copy_from_bbox(fig.bbox)
ax.draw_artist(line)

fig.canvas.blit(fig.bbox)

for i in range(10):
    
    if i % 2 == 0:
        z = np.random.randint(0, 500, size = (500, 500))
        line.set_clim(0, 500)

    else:
        z = np.random.randint(0, 200, size = (500, 500))
        line.set_clim(0, 200)

    fig.canvas.restore_region(bg)
    line.set_data(z)
    ax.draw_artist(line)
    fig.canvas.blit(fig.bbox)
    fig.canvas.flush_events()
    
    time.sleep(0.2)

I manually try to imitate the different ranges for matrix values and want to see colorbar tracking it.

Addition 1: Actually, the code will run as needed if I replace time.sleep() to plt.pause(). But I will be very thankful to all who could make it more clear for me.

0 Answers
Related