I have a python script I'm trying to debug and I'm using Pycharm Community Edition version 2016.3.2.
What I'd like to do is make some plots in the debug console (which I activate by setting a breakpoint and starting the debugger), but the problem is that the plot simply doesn't show up.
Some code to get a reproducible example of my problem is provided on the official matplotlib documentation here, in particular this bit of code:
import matplotlib.pyplot as plt
plt.ion()
plt.plot([1.6, 2.7])
What I find strange is that if I open a new python console from inside pycharm, when executing this code pycharm pops up a new window showing the plot, but this doesn't happen if I paste the same code in the "debug" console.
In both cases, I get the following output in the console
I found a potentially related post here, but frankly I can't tell if the two problems reduce to the same issue.
Tested in python 3.8.12, matplotlib 3.4.3, PyCharm 2021.2.3 (Professional Edition)
In PyCharm Create a Pure Python Project
File New Project... Pure Python
Finish the project setup
Create a new python file:
After the package imports, specify an interactive backend
mpl.use('Qt5Agg')
mpl.use('TkAgg')
import matplotlib.pyplot as plt
import matplotlib as mpl
# mpl.use('Qt5Agg') # interactive mode works with this, pick one
mpl.use('TkAgg') # interactive mode works with this, pick one
# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
explode = (0, 0.1, 0, 0)
fig1, ax1 = plt.subplots()
ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True, startangle=90)
ax1.axis('equal')
plt.show()
Debug Console
The script also works with debug, but the plot shows and then goes away as the debugger closes, so an extra line is included to prevent the debugger from closing the plot window.
Related
What exactly is the use of %matplotlib inline?
%matplotlib is a magic function in IPython. I'll quote the relevant documentation here for you to read for convenience:
IPython has a set of predefined ‘magic functions’ that you can call with a command line style syntax. There are two kinds of magics, line-oriented and cell-oriented. Line magics are prefixed with the % character and work much like OS command-line calls: they get as an argument the rest of the line, where arguments are passed without parentheses or quotes. Lines magics can return results and can be used in the right hand side of an assignment. Cell magics are prefixed with a double %%, and they are functions that get as an argument not only the rest of the line, but also the lines below it in a separate argument.
%matplotlib inline sets the backend of matplotlib to the 'inline' backend:
With this backend, the output of plotting commands is displayed inline within frontends like the Jupyter notebook, directly below the code cell that produced it. The resulting plots will then also be stored in the notebook document.
When using the 'inline' backend, your matplotlib graphs will be included in your notebook, next to the code. It may be worth also reading How to make IPython notebook matplotlib plot inline for reference on how to use it in your code.
If you want interactivity as well, you can use the nbagg backend with %matplotlib notebook (in IPython 3.x), as described here.
Provided you are running IPython, the %matplotlib inline will make your plot outputs appear and be stored within the notebook.
According to documentation
To set this up, before any plotting or import of matplotlib is
performed you must execute the %matplotlib magic command. This
performs the necessary behind-the-scenes setup for IPython to work
correctly hand in hand with matplotlib; it does not, however,
actually execute any Python import commands, that is, no names are
added to the namespace.
A particularly interesting backend, provided by IPython, is the
inline backend. This is available only for the Jupyter Notebook and
the Jupyter QtConsole. It can be invoked as follows:
%matplotlib inline
With this backend, the output of plotting commands is displayed inline
within frontends like the Jupyter notebook, directly below the code
cell that produced it. The resulting plots will then also be stored in
the notebook document.
To explain it clear:
If you don't like it like this:
add %matplotlib inline
and there you have it in your jupyter notebook.
If you want to add plots to your Jupyter notebook, then %matplotlib inline is a standard solution. And there are other magic commands will use matplotlib interactively within Jupyter.
%matplotlib: any plt plot command will now cause a figure window to open, and further commands can be run to update the plot. Some changes will not draw automatically, to force an update, use plt.draw()
%matplotlib notebook: will lead to interactive plots embedded within the notebook, you can zoom and resize the figure
%matplotlib inline: only draw static images in the notebook
It just means that any graph which we are creating as a part of our code will appear in the same notebook and not in separate window which would happen if we have not used this magic statement.
TL;DR
%matplotlib inline - Displays output inline
IPython kernel has the ability to display plots by executing code. The IPython kernel is designed to work seamlessly with the matplotlib plotting library to provide this functionality.
%matplotlib is a magic command which performs the necessary behind-the-scenes setup for IPython to work correctly hand-in-hand with matplotlib;
it does not execute any Python import commands, that is, no names are added to the namespace.
Display output in separate window
%matplotlib
Display output inline
(available only for the Jupyter Notebook and the Jupyter QtConsole)
%matplotlib inline
Display with interactive backends
(valid values 'GTK3Agg', 'GTK3Cairo', 'MacOSX', 'nbAgg', 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo', 'TkAgg', 'TkCairo', 'WebAgg', 'WX', 'WXAgg', 'WXCairo', 'agg', 'cairo', 'pdf', 'pgf', 'ps', 'svg', 'template')
%matplotlib gtk
Example - GTK3Agg - An Agg rendering to a GTK 3.x canvas (requires PyGObject and pycairo or cairocffi).
More details about matplotlib interactive backends: here
Starting with IPython 5.0 and matplotlib 2.0 you can avoid the use of
IPython’s specific magic and use matplotlib.pyplot.ion()/matplotlib.pyplot.ioff()
which have the advantages of working outside of IPython as well.
Refer: IPython Rich Output - Interactive Plotting
Starting with IPython 5.0 and matplotlib 2.0 you can avoid the use of
IPython’s specific magic and use
matplotlib.pyplot.ion()/matplotlib.pyplot.ioff() which have the
advantages of working outside of IPython as well.
ipython docs
If you don't know what backend is , you can read this:
https://matplotlib.org/stable/users/explain/backends.html
Some people use matplotlib interactively from the python shell and
have plotting windows pop up when they type commands. Some people run
Jupyter notebooks and draw inline plots for quick data analysis.
Others embed matplotlib into graphical user interfaces like wxpython
or pygtk to build rich applications. Some people use matplotlib in
batch scripts to generate postscript images from numerical
simulations, and still others run web application servers to
dynamically serve up graphs. To support all of these use cases,
matplotlib can target different outputs, and each of these
capabilities is called a backend; the "frontend" is the user facing
code, i.e., the plotting code, whereas the "backend" does all the hard
work behind-the-scenes to make the figure.
So when you type %matplotlib inline , it activates the inline backend. As discussed in the previous posts :
With this backend, the output of plotting commands is displayed inline
within frontends like the Jupyter notebook, directly below the code
cell that produced it. The resulting plots will then also be stored in
the notebook document.
Provided you are running Jupyter Notebook, the %matplotlib inline command will make your plot outputs appear in the notebook, also can be stored.
I think that with recent versions of Jupyter/matplotlib, the figures are plotted "inline" without the need to use %matplotlib inline.
So one might think that this command is now useless… but to my understanding, it creates a "manager" which configures the plotting parameters. Matplotlib looks for an existing manager when creating a figure, and creates one if necessary. Inside matplotlib.pyplot.figure:
manager = _pylab_helpers.Gcf.get_fig_manager(num)
if manager is None:
# not relevant stuff…
manager = new_figure_manager(
num, figsize=figsize, dpi=dpi,
facecolor=facecolor, edgecolor=edgecolor, frameon=frameon,
FigureClass=FigureClass, **kwargs)
Now, setting a plotting parameter (rcParams) will not create a "manager" by itself. So when plotting a figure for the first time, a new manager will be created and will overwrite your parameters.
Comment/un-comment the %matplotlib inline and see what happens. (Do not forget to restart the kernel between each try!)
import matplotlib.pyplot as plt
from matplotlib.image import imread
# %matplotlib inline
plt.rcParams["figure.dpi"] = 200
plt.imshow(imread("path_to_your_image"))
print(plt.rcParams["figure.dpi"])
It is not mandatory to write that. It worked fine for me without (%matplotlib) magic function.
I am using Sypder compiler, one that comes with in Anaconda.
I'm trying to open any matplotlib chart in the interactive mode in Python Interactive in vscode (Windows)
I tried to use magic
%matplotlib qt
and sometimes it works, but, very often, it just 'blinks' (open chart window and close it instantly, I don't know why) and shows chart in Python Interactive instead
I have tried plt.ion() but it seems that it doesn't change anything.
What is the right way of an opening chart in interactive mode?
If you want to show the plot in a separate window, you may need to set a backend. Also, your selected backend may not be compatible with your setup, so try a few.
In [4]: plt.switch_backend('QtAgg4')
If you DO want to show plots inline, you do not need to do anything. By default, VS Code will show the plots inline. You do not need %matplotlib inline, or plt.show(). If you DO want plots inline and it's not working, try:
get_ipython().run_line_magic('matplotlib', 'inline')
This is what shows up when you convert a jupyter notebook into VS Code by importing it.
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0,100)
y = x*2
# Functional Method
fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1])
ax.plot(x, y)
ax.set_title('title')
ax.set_xlabel('X')
ax.set_ylabel('Y')
My Code, tested on my VS Code in Interactive Window, with plot showing inline.
Updated answer as of Nov 2019:
This problem is gone with the recent update to VS Code. Make sure to install all Jupyter Notebook extensions. Also, you can now right-click on a .ipynb file and select "Open-With VS Code". This will automatically open the file in 2 windows, raw-json-code on left and interactive-jupyter-notebook on right. Slick. Really love this new update to VS Code.
I'm a developer on the Interactive Window. Jennifer has already given some good advice above for getting pop out plots working with our current builds. But if you are interested, we just recently added a plot viewer to our newest development builds. You can see the issue here:
https://github.com/microsoft/vscode-python/issues/4976
It won't be in our full release until our next monthly release. But if you want to try it out early and see if it works for you, you can check out our dev build here:
https://github.com/microsoft/vscode-python/blob/master/CONTRIBUTING.md#development-build
The following python script does not display a figure anymore, as it used to on my machine:
import matplotlib.pyplot as plt
plt.scatter(1, 1)
plt.show() # Blocks and opens a graphical window as usual.
plt.ion()
plt.scatter(1, 1) # Does *not* open a graphical window anymore as I expect.
plt.scatter(2, 2) # Does *not* update the graphical window anymore as I expect (there is still no window at all)
plt.ioff()
plt.show() # The window opens at last, but it's blocking.
I also note that graphical windows style has changed (bottom bar):
My guess is that it is because my Arch system has recently upgraded to matplotlib 3.0.3-1. But I see nothing about a major change in ion() on their What's New page.
What could be causing this?
How do I get a non-blocking plot progressively updating like I used to get between two ion() and ioff() invokations?
[UPDATE] I can confirm that downgrading to matplotlib 2.2.3-2 does revert to expected behaviour. The problem thus seems to lie within recent upgrades of matplotlib or its environment.
[UDPATE] Filed on matplotlib issue tracker.
When I execute the pyplot.figure() in the Python shell of the Enthought Canopy editor a graph menu is displayed. But when I run the following script, no graph menu is displayed?
from matplotlib import pyplot
def ex1():
pyplot.figure()
if __name__ == "__main__":
ex1()
Edit: I received the following message after re-executing the script a 'few' times. But I see not a single figure.
C:\Users\Matthias\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\pyplot.py:412: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (matplotlib.pyplot.figure) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam figure.max_num_figures).
max_open_warning, RuntimeWarning)
Edit2: This seems to work fine.
import pylab
def ex1():
pylab.figure()
pylab.show()
if __name__ == "__main__":
ex1()
show() is the final step of the normal programming sequence when plotting with matplotlib: assemble all your components, then show the result.
In IPython running in pylab or matplotlib modes (Canopy, by default runs IPython in pylab mode), plot commands done directly at the IPython prompt are displayed one by one as you enter them. This is a special IPython feature to let you interact with your plots. (The "I" in IPython stands for interactive.)
I just installed matplotlib in Ubuntu 9.10 using the synaptic package system.
However, when I try the following simple example
>>> from pylab import plot;
>>> plot([1,2,3],[1,2,3])
[<matplotlib.lines.Line2D object at 0x9aa78ec>]
I get no plot window. Any ideas on how to get the plot window to show?
You can type
import pylab
pylab.show()
or better, use ipython -pylab.
Since the use of pylab is not recommended anymore, the solution would nowadays be
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.show()
pylab.show() works but blocks (you need to close the window).
A much more convenient solution is to do pylab.ion() (interactive mode on) when you start: all (the pylab equivalents of) pyplot.* commands display their plot immediately. More information on the interactive mode can be found on the official web site.
I also second using the even more convenient ipython -pylab (--pylab, in newer versions), which allows you to skip the from … import … part (%pylab works, too, in newer IPython versions).
Try this:
import matplotlib
matplotlib.use('TkAgg')
BEFORE import pylab
The code snippet below works on both Eclipse and the Python shell:
import numpy as np
import matplotlib.pyplot as plt
# Come up with x and y
x = np.arange(0, 5, 0.1)
y = np.sin(x)
# Just print x and y for fun
print x
print y
# Plot the x and y and you are supposed to see a sine curve
plt.plot(x, y)
# Without the line below, the figure won't show
plt.show()
Any errors show up? This might an issue of not having set the backend. You can set it from the Python interpreter or from a config file (.matplotlib/matplotlibrc) in you home directory.
To set the backend in code you can do
import matplotlib
matplotlib.use('Agg')
where 'Agg' is the name of the backend. Which backends are present depend on your installation and OS.
http://matplotlib.sourceforge.net/faq/installing_faq.html#backends
http://matplotlib.org/users/customizing.html
Modern IPython uses the "--matplotlib" argument with an optional backend parameter. It defaults to "auto", which is usually good enough on Mac and Windows. I haven't tested it on Ubuntu or any other Linux distribution, but I would expect it to work.
ipython --matplotlib
If you encounter an issue in which pylab.show() freezes the IPython window (this may be Mac OS X specific; not sure), you can cmd-c in the IPython window, switch to the plot window, and it will break out.
Apparently, future calls to pylab.show() will not freeze the IPython window, only the first call. Unfortunately, I've found that the behavior of the plot window / interactions with show() changes every time I reinstall matplotlib, so this solution may not always hold.
If you are starting IPython with the --pylab option, you shouldn't need to call show() or draw(). Try this:
ipython --pylab=inline
--pylab no longer works for Jupyter, but fortunately we can add a tweak in the ipython_config.py file to get both pylab as well as autoreload functionalities.
c.InteractiveShellApp.extensions = ['autoreload', 'pylab']
c.InteractiveShellApp.exec_lines = ['%autoreload 2', '%pylab']
If you are user of Anaconda and Spyder then best solution for you is that :
Tools
-->
Preferences
-->
Ipython console
-->
Graphic Section
Then in the Support for graphics (Matplotlib) section:
select two avaliable options
and in the Graphics Backend:
select Automatic
Another possibility when using easy_install is that you need to require the most recent version of matplotlib.
Try:
import pkg_resources
pkg_resources.require("matplotlib")
before you import matplotlib or any of its modules.