Very low Performance for large interactive interfaces

I have been having some issues with very low plotting speeds for interactive usage even with blitting.
I recently realized that this the speed is heavily related to the size of the figure.
So for example using the code bellow (basically the one available here: Faster rendering by using blitting — Matplotlib 3.7.1 documentation)

import matplotlib.pyplot as plt
import numpy as np
import time
class BlitManager:
    def __init__(self, canvas, animated_artists=()):
        """
        Parameters
        ----------
        canvas : FigureCanvasAgg
            The canvas to work with, this only works for subclasses of the Agg
            canvas which have the `~FigureCanvasAgg.copy_from_bbox` and
            `~FigureCanvasAgg.restore_region` methods.

        animated_artists : Iterable[Artist]
            List of the artists to manage
        """
        self.canvas = canvas
        self._bg = None
        self._artists = []

        for a in animated_artists:
            self.add_artist(a)
        # grab the background on every draw
        self.cid = canvas.mpl_connect("draw_event", self.on_draw)

    def on_draw(self, event):
        """Callback to register with 'draw_event'."""
        cv = self.canvas
        if event is not None:
            if event.canvas != cv:
                raise RuntimeError
        self._bg = cv.copy_from_bbox(cv.figure.bbox)
        self._draw_animated()

    def add_artist(self, art):
        """
        Add an artist to be managed.

        Parameters
        ----------
        art : Artist

            The artist to be added.  Will be set to 'animated' (just
            to be safe).  *art* must be in the figure associated with
            the canvas this class is managing.

        """
        if art.figure != self.canvas.figure:
            raise RuntimeError
        art.set_animated(True)
        self._artists.append(art)

    def _draw_animated(self):
        """Draw all of the animated artists."""
        fig = self.canvas.figure
        for a in self._artists:
            fig.draw_artist(a)

    def update(self):
        """Update the screen with animated artists."""
        cv = self.canvas
        fig = cv.figure
        # paranoia in case we missed the draw event,
        if self._bg is None:
            self.on_draw(None)
        else:
            # restore the background
            cv.restore_region(self._bg)
            # draw all of the animated artists
            self._draw_animated()
            # update the GUI state
            cv.blit(fig.bbox)
        # let the GUI event loop process anything it has to do
        cv.flush_events()



# make a new figure
fig, ax = plt.subplots()
fig.set_figheight(7), fig.set_figwidth(15)

# add a line
x = np.linspace(0, 2 * np.pi, 1000)
(ln,) = ax.plot(x, np.sin(x), animated=True)
# add a frame number
fr_number = ax.annotate(
    "0",
    (0, 1),
    xycoords="axes fraction",
    xytext=(10, -10),
    textcoords="offset points",
    ha="left",
    va="top",
    animated=True,
)
bm = BlitManager(fig.canvas, [ln, fr_number])
# make sure our window is on the screen and drawn
plt.show(block=False)
plt.pause(.1)

last = (time.time_ns()//1_000_000)
for j in range(1000):
    # update the artists
    ln.set_ydata(np.sin(x + (j / 100) * np.pi))
    fr_number.set_text("ms since last frame: {j}".format(j=(time.time_ns()//1_000_000 - last)))
    last = (time.time_ns()//1_000_000)
    # tell the blitting manager to do its thing
    bm.update()

By comenting or uncomenting the fig.set_figheight(7), fig.set_figwidth(15) line there is a 3x times difference in the time between frames.

In my case I get 30ms per frame with the basic image size and more than 120ms for the 7x15 size.

Is this just the natural way the plotting works? Is there any way to combat or avoid it?

My understanding is that blitting renders a rasterised image as the background, literally a bitmap array the size of the figure. 7*15 / 4.8*6.4 =3.41796875 , so you would expect the smaller plot to update ~3.4x faster. I guess this drops to your x4 faster as some parts of the graph scale linearly (yaxis, xaxis, line2D etc). I don’t think there is a way to get round this unless the plot is simple enough to avoid blitting altogether?

> fig, ax = plt.subplots()
> fig.get_figheight(), fig.get_figwidth()
(4.8, 6.4)