0

I am using matplotlib FuncAnimation to display data received in real time from sensors.

Before updating matplotlib, I was using matplotlib 3.2.2 and the behavior was the following:

  • graph opens and autoscales axes limits to the data coming in from the sensors
  • if I interactively zoom in on the graph, the graph remains on the zone I defined (which is convenient to inspect a small portion of the data).

Now, after updating to matplotlib 3.3.4, the graph still opens and autoscales, but if I zoom in on the data, the graph immediately autoscales back to the full extent of the data, which makes inspecting impossible.

I have tried setting the axes autoscaling to False, but then the graph does not autoscale at all, which is not convenient.

I have put below some example code that reproduces the phenomenon described above:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from random import random

def test():
    """Test live matplotlib animation"""

    fig, (ax1, ax2) = plt.subplots(2, 1)

    # for ax in ax1, ax2:  # uncomment to deactivate autoscale
    #    ax.set_autoscale_on(False)

    def animate(i):

        x = random()           # Fake sensor 1
        y = 10 * random() + 3  # Fake sensor 2

        ax1.plot(i, x, 'ok')
        ax2.plot(i, y, 'ob')

    ani = FuncAnimation(fig, animate, interval=100)
    plt.show()

    return ani

Any idea how to get back to the initial behavior while keeping a more recent version of matplotlib? Thank you very much in advance!

1 Answers1

0

The workaround I have found is to use a callback to mouse events on the matplotlib figure, that deactivates autoscaling when there is a left click, and reactivates them with a right click.

def onclick(event):
    ax = event.inaxes
    if ax is None:
        pass
    elif event.button == 1:  # left click
        ax.set_autoscale_on(False)
    elif event.button == 3:  # right click
        ax.set_autoscale_on(True)
    else:
        pass

cid = fig.canvas.mpl_connect('button_press_event', onclick)

This means that whenever the user uses interactive zooming in some axes of the figure (by left clicking to define the zoom area), autoscaling is deactivated and inspection, panning etc. are possible. The user then just has to right-click to go back to the autoscaled, real-time data.

In fact this is even better than what I had initially in matplotlib 3.2.2, where once zooming was done, there was no way to go back to autoscaled axes limits.