Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Last active December 1, 2023 05:39
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CMCDragonkai/9a34531e4a96842b07bd6e91a23e0f3c to your computer and use it in GitHub Desktop.
Save CMCDragonkai/9a34531e4a96842b07bd6e91a23e0f3c to your computer and use it in GitHub Desktop.
Interactive Matplotlib (while in REPL) #python #matplotlib

Interactive Matplotlib (while in REPL)

Matplotlib can be used in an interactive manner either in the REPL or as part of a script. Let's assume you're using export MPLBACKEND='Qt4Agg'.

To do this you need to switch on interactive mode:

import matplotlib.pyplot as plt
plt.ion()

If you are using ipython you can instead use %matplotlib magic command at the REPL. Or you can use:

from IPython import get_ipython
get_ipython().magic('%matplotlib')

Let's say we want to interactively show 2 figures with plots. Wait for 5 seconds. And then close both figures.

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

plt.ion()

arr = np.arange(10)

fig1 = plt.figure()
fig1ax1 = fig1.subplots()
fig1ax1.plot(arr)
plt.pause(0.1)

fig2 = plt.figure()
fig2ax1 = fig2.subplots()
fig2ax1.plot(arr)
plt.pause(0.1)

time.sleep(3)
plt.close(fig1)
plt.close(fig2)

As soon as you run plt.figure(), a figure window is created. However as it is running asychronously it is not running in a separate thread. Instead the Python main loop continues until it reaches a blocking IO action, at that point the figure will actually be displayed. To prevent this behaviour we use plt.pause(0.1) to allow the GUI event loop to draw the figure. The value of seconds here being 0.1 seconds is dependent on the speed of your computer. Note that you cannot use time.sleep() here probably because the matplotlib event loop doesn't work the same way as Python multithreading. Also apparently matplotlib is not thread safe.

Let's consider another possibility. In this case we want to draw 2 figures, continue doing other things, and then at the very end block the program until the figures are closed.

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

plt.ion()

arr = np.arange(10)

fig1 = plt.figure()
fig1ax1 = fig1.subplots()
fig1ax1.plot(arr)
plt.pause(0.1)

fig2 = plt.figure()
fig2ax1 = fig2.add_subplot(1, 1, 1)
fig2ax1.plot(arr)
plt.pause(0.1)

plt.show(block=True)

Here you can either close the Python program which will close all the figures, or you can close each figure individually via your GUI.

Note that if you don't actually care to render a figure immediately, you can wait until the final plt.show(block=True). This may speed your program up.

Finally note that if you want to close a figure you MUST use plt.close(fig), not just del fig. It requires explicit closing. To do this automatically you can use a bracketing pattern with a context manager. After you have done that, you can run del fig. In this way you have cleaned up the GUI figure, and then afterwards delete the figure variable completely (because some garbage is still left even after plt.close(fig)).

When using Matplotlib in an interactive session, it can be easier to use imperative commands rather than the OOP API.

import matplotlib.pyplot as plt

# if you don't have this
# you need to use explicit show()
# having this on ensures you cannot forget about created figures
plt.ion()

# side effect of creating a figure window
plt.figure()
# side effect of painting the image
plt.imshow(arr)

# side effect of creating another figure window
plt.figure()
plt.imshow(arr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment