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.

Russell Burdt
  • 2,391
  • 2
  • 19
  • 30

3 Answers3

3

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()
ilke444
  • 2,641
  • 1
  • 17
  • 31
  • 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. – Russell Burdt Apr 13 '20 at 21:47
  • Did you delete `plt.show()` before `set_trace()` after enabling `plt.ion()`? – ilke444 Apr 14 '20 at 05:43
  • I ran exactly the code in the answer without any changes. – Russell Burdt Apr 14 '20 at 16:27
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.

Paul Brodersen
  • 11,221
  • 21
  • 38
  • 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). – Russell Burdt Apr 16 '20 at 18:59
  • @RussellBurdt Yes, scenario 3 should enter the debugger with the figure rendered. python 3.6.8 and matplotlib 3.2.1. , ipdb 0.12. – Paul Brodersen Apr 17 '20 at 10:57
  • @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](https://stackoverflow.com/a/20528503/2912349). Also, what happens if you use `plt.pause(1.)` instead of `plt.show()` (trying to see if there are any race conditions). – Paul Brodersen Apr 17 '20 at 11:04
  • 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. – Russell Burdt Apr 17 '20 at 21:13
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

Keren
  • 167
  • 2
  • 12