matplotlib automatically shows figure - matplotlib

I am using matplotlib version 3.0.3 in Eclipse Oxygen 3 on Windows 10.
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=4, ncols=4) # Figure is shown!?
plt.show() # expected to see figure only here
It seems that whenever a plt method gets called matplotlib already opens the UI.
That is useful while debugging but I usually want to just savefig and not stop to look at the generated image ...
This used to work fine for me on my previous Window 7 laptop (not sure what matplotlib version).
Has something changed in the default behavior which I cannot find documented?

Stepping into the matplotlib code I've discovered that interactive mode was set -- probably by default as I don't have a matplotlibrc file anywhere.
I added matplotlib.interactive(False) at the beginning of main() to solve this.
Apparently I still get the interactive mode when debugging even with the above line, so this is good enough for me (for now).

Related

Matplotlib background won't match vscode theme

When I create a matplotlib chart in my jupyter notebook in vscode, it gives the whole cell a white background. I've tried putting
"import matplotlib.pyplot as plt",
"plt.style.use('dark_background')"
in my settings file to run as startup commands and that makes it gives the plot a black background, but it still doesn't match my vscode theme. Does anyone know how to make them match seamlessly? transparent chart background mabye?
The white background is actually on purpose so that it matches what Jupyter would show. It's from reading the 'needs_background' element of the matplotlib output.
The background unfortunately will always be either white or black based on the 'needs_background' element. (As you found with your style of 'dark_background')
The code for that is here:
https://github.com/microsoft/vscode-notebook-renderers/blob/91210f63be0fcca92d7ea9125b7e9445a423b0a4/src/client/render.tsx#L70
You can enter a request for the jupyter extension to change that color here:
https://github.com/microsoft/vscode-jupyter/issues
You can plot your chart in a PyQt5 window.
I am not sure if this solves your problem, but it's a way to make the chart transparent. I hope it's helpful:
You need to import PyQt5 (pip3 install PyQt5).
from PyQt5 import QtCore
The code to create the transparent window is inserted after defining your figure:
window = plt.gcf().canvas.manager.window # used to get your figure
window.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
window.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
window.setStyleSheet("background:transparent")
Finally show the window with plot.show():
plt.show()

jupyter & matplotlib - how to turn on and off the interactive mode on a figure

Question
In Jupyter notebook, is it possible to turn off the interactive mode on a figure? The ax.plot() does not show a line when running from the command line python but in a Jupyter notebook cell, it shows up.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(7,5))
plt.ioff()
ax.plot([1.6, 2.7]) # <--- Still the line shows up in a jupyter notebook
...
plt.ion()
plt.draw()
plt.show()
Version
$ jupyter notebook --version
6.2.0
from platform import python_version
print(python_version())
3.8.8
Related
matplotlib python inline on/off suggests using %matplotlib but not sure why using the magic command to turn on/off the interactive mode.
It also has a mention below but not sure what it exactly means.
on and ioff set interactive mode, determining if the plot is updated after each plotting command (interactive mode on) or it waits plt.show() (if interactive mode is off). This is independent on inline, that decides if the notebook or the console should display the graphics (this happens any time the plot is updated, meaning at every plotting command if interactive mode is set with ion, or after plt.plot if unset with ioff).
Quibbler might be of some help here:
https://github.com/Technion-Kishony-lab/quibbler
It helps create interactive graphics in matplotlib.
for transparency: I am one of the developers of Quibbler.

Spyder interactive plot : wait for the plot to be closed to continue

I'm working with windows using Spyder, I plot with matplotlib. My problem is that I want to do interactive plot (or sometimes plotting a lot of things) and I want spyder to wait that I close the figure to continue the code (same way as a traditional terminal would).
I tried
plt.ion(),
%mpl TkAgg
before loading matplotlib, Ipython and python console... And I can't find any solution.
If you want an example, the goal is that the "hello" prints only when I close the figure, with Spyder on windows 10.
import matplotlib.pyplot as plt
plt.figure('Close me to get hello')
plt.plot(0,0,'*')
plt.show()
print("hello")
You need to deactivate Spyder's Matplotlib support by going to
Tools > Preferences > IPython console > Graphics
and deselecting the option called
Activate support
Then you need to change your code like this
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
plt.figure('Close me to get hello')
plt.plot(0,0,'*')
plt.show()
print("hello")
to set your backend (TkAgg in this case) by hand before creating your plot.
When I run the code, the desired behaviour of the plot window blocking subsequent code from being executed is already there. So I guess there are some other settings involved. For that reason I also cannot test the following, but I would suppose that you need to turn the interactive mode off before calling show.
import matplotlib.pyplot as plt
plt.ion() # turn interactive on, if it isn't already
plt.figure('Close me to get hello')
plt.plot(0,0,'*')
plt.draw()
# possibly do other stuff that would make the use of interactive mode useful
plt.ioff() # turn interactive off
plt.show()
print("hello")

ipython & matplotlib:chart doesn't show in ipython

Any help with the issue is appreciated. As the following photo shows, I am trying to get an horizontal bar chart and always get instead. I don't know what to do with it.
Reposting as an answer:
If you run the %matplotlib magic in IPython before creating plots, the plots will appear automatically, and won't block the prompt.
We're working with matplotlib so that this won't be necessary in matplotlib 2.0.

PyPlot show() really slow after calling PyQt4.QFileDialog.getOpenFileNames()

For an analysis application I'm trying to:
Get a list of filenames from the user using PyQt4 QFileDialog
Extract some data from each file
Plot the aggregated data using pyplot
However, getting the filenames this way causes pyplot.show() to take a really, really long time. I've distilled the problem down to the following test case:
import matplotlib.pyplot as plt
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication(None)
fd = QtGui.QFileDialog(None)
filenames = fd.getOpenFileNames(caption='Select Data Files')
plt.plot([1,2,3,4,5])
plt.show()
Note that I'm not even doing anything with the filenames here--just getting them.
Selecting a single file from the dialog results in a plot time of 10 seconds. Interestingly, the time required for show() to complete goes up roughly linearly with the number of files selected. For 10 files it takes about 67 seconds for the plot to show.
This isn't a big deal for plotting data from a handful of files, but when aggregating data from Monte Carlo simulations where there are thousands of files it can take literally hours for the plot to show. Telling matplotlib to use the Qt4Agg backend results in the same behavior.
If I comment out the call to getOpenFileNames the script will complete in under a second.
I'm running the following versions of the relevant packages (should be latest):
Python 2.7
matplotlib 1.3.1
python-sip 4.13.2-1
python-qt4 4.9.1-2ubuntu1
python-sip-dev 4.13.2-1
python-qt4-dev 4.9.1-2ubuntu1
I uninstalled sip, qt4 and reinstalled them--same issue. I've seen the issue accross two separate machines--both running 32-bit Ubuntu 12.04.
Any help would be much appreciated--I've wasted an embarrassing amount of time waiting for plots to show.
Updates:
The type and name of the files selected doesn't seem to matter.
Cancelling or exiting the file dialog box results in no delay and an immediate plot.
Running the script as sudo eliminates the issue; however, the file dialog looks different when I run as sudo and may be using a different gui backend that doesn't conflict with pyplot's use of PyQt, so may be a red herring.
The program doesn't hang in getOpenFileNames, it hangs on the next call that uses PyQt. Whether that's a plot or another file dialog doesn't seem to matter--the first file dialog blocks both.
Calling app.processEvents() after running the dialog doesn't help.
Using PySide in place of PyQt4 results in the same behavior.
Using getOpenFileName instead of getOpenFileNames results in the same behavior.
Running getOpenFileNames with the DontUseNativeDialog option works (no delay)
None of the other QFileDialog options have any effect (ShowDirsOnly, DontResolveSymlinks, DontConfirmOverwrite, ReadOnly, HideNameFilterDetails, DontUseSheet)