render matplotlib figure from debugger

Viewed 1536

Cannot get the following code to do all three things:

  1. stop at the debug breakpoint
  2. render the figure
  3. return control to the console with the figure rendered (in debugger mode)
import matplotlib.pyplot as plt
from ipdb import set_trace

fig, ax = plt.subplots()
ax.plot(range(10))
plt.show()
set_trace()

The use case to do all three things simultaneously is debugging inside of a module that requires information in the matplotlib visualization.

Running IPython from the console as ipython --pylab accomplishes (1) and (3) above only, as shown below. Using plt.ion() in the code does the same. The debugger is available but the visualization will not render. enter image description here

Running IPython from the console as just ipython, or running python <script.py>, accomplishes (1) and (2) above only, as shown below. The visualization has rendered but the debugger is not available. enter image description here

Right now I am using python 3.7.7, matplotlib 3.1.3 with Qt5Agg backend, ipython 7.13.0, and ipdb 0.12.3.

3 Answers

If you enable the interactive mode using ion(), you can achieve it while running python <script.py>. It will show the plots (by calling draw) immediately after plot and leave the control back to the console at set_trace.

import matplotlib.pyplot as plt
from ipdb import set_trace

# Enable interactive mode
plt.ion() 
fig, ax = plt.subplots()
# Shown immediately
ax.plot(range(10))
set_trace()

Scenario 1

import matplotlib.pyplot as plt
from ipdb import set_trace
fig, ax = plt.subplots()
ax.plot(range(10))
plt.show()
set_trace()

In your example, you are

  1. in ipython,
  2. not in interactive mode.

Hence, plt.show() blocks execution of the rest of the script until the figure is closed.

Scenario 2

import matplotlib.pyplot as plt
from ipdb import set_trace

# Enable interactive mode
plt.ion() 
fig, ax = plt.subplots()
ax.plot(range(10))
# Shown immediately
set_trace()

With @ilke444 code you are in interactive mode. However, interactive mode works a little bit differently then @ilke444 expects, given the code comment. It does not force a draw immediately but when control is returned to the REPL, in your case ipython. However, we never get there as we enter the debugger before that happens.

Scenario 3

import matplotlib.pyplot as plt
from ipdb import set_trace

# Enable interactive mode
plt.ion() 
fig, ax = plt.subplots()
ax.plot(range(10))
plt.show() # or: fig.canvas.draw() or plt.pause()
set_trace()

@ilke444 suggestion in the comment works because we actually force the figure draw before entering the debugger.

I encountered a similar problem in the following situation: I am running on debug mode on Pycharm and stopped in a certain place Then I tried to run a function in the debug console that's supposed to plot figures using matplotlib.pyplot and it didn't

The solution was to actually delete the plt.show() at the end of the function now it works

Related