3

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 3

3
+25

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()
Sign up to request clarification or add additional context in comments.

3 Comments

Including plt.ion() in the code as you have it gives control to the debugger but does not render the visualization until the debugger is closed. Some images were added to the original post to clarify.
Did you delete plt.show() before set_trace() after enabling plt.ion()?
I ran exactly the code in the answer without any changes.
1

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.

4 Comments

Scenario 3 (for my environment) is not entering the debugger with the figure rendered. This is true whether I execute from the terminal (python script.py) or enter ipython (with or without --pylab) and then execute (%run script.py). Could you please confirm you mean that Scenario 3 should enter the debugger with the figure rendered. And also please confirm your versions for python and matplotlib (also ipdb if that matters).
@RussellBurdt Yes, scenario 3 should enter the debugger with the figure rendered. python 3.6.8 and matplotlib 3.2.1. , ipdb 0.12.
@RussellBurdt It starts to sound like a bug. Can you switch to a different backend before importing matplotlib, and then just run from the command line? Try to avoid ipython with the --pylab flag, even the ipython developers think it was a mistake. Also, what happens if you use plt.pause(1.) instead of plt.show() (trying to see if there are any race conditions).
Going to python 3.6.8, matplotlib 3.2.1, and ipdb 0.12.3 did not get Scenario 3 (exactly as you have it) working. debugger mode was entered but the figure did not render. As well, adding import matplotlib then matplotlib.use('Qt4Agg') before all of Scenario 3 did the same. Modifying Scenario 3 by replacing plt.show() with plt.pause(1) entered the debugger and rendered the figure, however the interactive features of the figure (zoom, pan, etc.) were then subsequently blocked.
0

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

1 Comment

If I do that, the figure doesn't even show... How exactly did you do it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.