Updating a text in a plot usin Artist (or any other way you may suggest)$

Hello, I am learning this wonderful library.

I am trying to update a plot as fast as possible. I posted this question in other forums and found no solution. The quickest way I found so far is in this post, where a line plot updates very quickly using a while loop. This is the relevant piece of code:

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

fig, ax  = plt.subplots()
line,  = ax.plot(np.random.randn( 100 ))

fig.canvas.draw()
plt.show(block = False )
 
tstart  = time.time()
num_plots  = 0

while time.time() - tstart <  5 :
     line.set_ydata(np.random.randn( 100 ))
     ax.draw_artist(ax.patch)
     ax.draw_artist(line)
     fig.canvas.blit(ax.bbox)
     fig.canvas.flush_events()
     num_plots  + = 1

The speed of that execution is perfect for my needs. The problem is that I need to also include text in the plot, and this text should be updated too in each iteration. I have tried so far updating the plot title and related ways but the text is only updated when the while loop finishes.

I feel the answer must be in Artist documentation, but given my introductory knowledge of matplotlib it seems to be ‘hidden’ yet for me. What am I missing? I just need a text in any place in the plot, showing the iteration number (eg the value of num_plots in the example above).

Thanks!

[@tacaswell edited to fix markup]

Setting the title will technically work, but in this code you are only updating the area inside of the Axes (that is what the ax.bbox in fig.canvas.blit(ax.bbox) does).

A complete tutorial on blitting is at https://matplotlib.org/tutorials/advanced/blitting.html and the animation module (https://matplotlib.org/api/animation_api.html#module-matplotlib.animation) may provide you with some helpful tools for managing this.

To add text I would use an ax.annotate (https://matplotlib.org/tutorials/text/annotations.html#annotations / https://matplotlib.org/gallery/text_labels_and_annotations/annotation_demo.html ). If you place it with in the Axes you can then use the same code as above but add txt.set_text(...)

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

fig, ax = plt.subplots()
(line,) = ax.plot(np.random.randn(100))
txt = ax.annotate(
    "",
    xy=(1, 1),
    xycoords="axes fraction",
    ha="right",
    va="top",
    xytext=(-5, -5),
    textcoords="offset points",
)
fig.canvas.draw()
plt.show(block=False)

tstart = time.time()
num_plots = 0

while time.time() - tstart < 5:
    line.set_ydata(np.random.randn(100))
    txt.set_text(f"frame {num_plots}")
    ax.draw_artist(ax.patch)
    ax.draw_artist(line)
    ax.draw_artist(txt)
    fig.canvas.blit(ax.bbox)
    fig.canvas.flush_events()
    num_plots += 1

Great! This is exactly what I needed, thanks a lot!!