This question already has answers here:
warning about too many open figures
(7 answers)
Closed 5 years ago.
I am using Matplotlib and MPLD3 to create graphs that can be displayed in html plages (using django). Currently my graphs are being generated dynamically from data being pulled from csv files. Every so often I get this message in my Terminal:
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)
I am not really sure what it means, but I am assuming it means I should have some way of closing graphs that are not in use. Is there anyway to do this or am I completely off base? Thanks.
I preferred the answer of tacaswell in the comments, but had to search for it.
Clean up your plots after you are done with them:
plt.close(fig)
or
plt.close('all')
Figures will automatically be closed (by garbage collection) if you don't create them through the pyplot interface. For example you can create figures using:
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
def new_fig():
"""Create a new matplotlib figure containing one axis"""
fig = Figure()
FigureCanvas(fig)
ax = fig.add_subplot(111)
return fig, ax
(Based on this answer)
Related
I am trying to create a function that will accept a figure handle from a closed matplotlib figure and use that handle to reshow the figure. The below code will do this however the navigation toolbar is still linked to the old (destroyed) figure so plot interactivity is lost. Is there a way of linking the navigation toolbar to the new window so the plot is interactive?
For reference, I have consulted similar questions:
Matplotlib: how to show a figure that has been closed
Re-opening closed figure matplotlib
Matplotlib: re-open a closed figure?
The solution (if it exists) should not require use of a bespoke backend. I am hoping this is possible with whatever backend is default (which changes with different OS). I'm also looking to do this without relying on iPython.
My partially complete solution (which lacks navigation bar interactivity in the reshown figure) is:
import matplotlib.pyplot as plt
def reshow_figure(handle):
figsize = handle.get_size_inches() # get the size of the old figure
fig_new = plt.figure() # make a new figure
new_manager = fig_new.canvas.manager # get the figure manager from the new figure
new_manager.canvas.figure = handle # assign the old figure to the new figure manager
handle.set_canvas(new_manager.canvas) # assign the new canvas to the old figure
handle.set_size_inches(figsize) # restore the figsize
plt.show() # show the resurrected figure
plt.plot([1,2,3,4,5],[1,5,3,4,2])
fig = plt.gcf() # get the figure handle to resurrect the figure later
plt.title('My Figure') # just to check the title copies across
plt.gcf().set_size_inches((10,5)) # set a custom size to test recovery of the figsize
plt.show()
# manually close the figure window
reshow_figure(fig)
I have a script that runs repeatedly and in the process it saves a figure into a folder. After a while I start getting warnings about too many open figures in memory.
I checked other questions on the topic, for example, this one and added plt.close('all') to my code so now it looks like this:
fig, ax = plt.subplots(figsize=(17,8))
plt.hist(results_df['Diff'], bins=100, density=True, histtype='step')
plt.savefig(f'backtester_results/figures/rf_model_{n_days}_data_and_{lag}_lag.png',
format='png')
plt.close('all')
And yet I keep getting figures piled up in memory and warnings after a while. Where did I go wrong?
Here's the warning:
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.
When reading in the official documentation I would assume that plt.close('all') only closes the windows without removing the figures (https://matplotlib.org/1.3.0/api/pyplot_api.html#matplotlib.pyplot.close).
As I understand you would need to clear the figure as follows:
fig.clf()
plt.close()
Source: (How can I release memory after creating matplotlib figures)
This question already has an answer here:
view and then close the figure automatically in matplotlib?
(1 answer)
Closed 1 year ago.
So I got a small problem, but yeah, I need an answer. A created a plot with matplotlib, and after the showing I want to close it.
Of course, I visited some documentation (e.g.: https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.close.html), a lot of forums, like that: matplotlib close does not close the window, but my code isn't working for me.
I used the plt.ion() function, but when I tryed it, the plot wasn't appearing, I just saw an empty window.
After that, I used the plt.show(block = False) and I again got an empty window.
You can see the code above:
#Showing
plt.ion()
plt.show(block = False)
time.sleep(10)
plt.close("all")
As you can see, there's a delay, I would like to see a plot for ten seconds, and after close it.
Feel free, to comment to me, I appreciate that, thank you.
Do not use time.sleep(). Use the plt.pause() function.
Details/Explanation: First, you need plt.show(block=False) so that the plot is not blocked and the code executes the next command.
Second, the second command i.e. plt.pause(3) pauses the plot for 3 seconds and then goes to the next line/command.
Finally, the last line/command, plt.close("all") closes the plot automatically.
This is a script (.py) that plots an imshow and automatically close it after 3 seconds.
import matplotlib.pyplot as plt
import numpy as np
X = np.random.rand(10,10)
plt.imshow(X)
plt.show(block=False)
plt.pause(3) # 3 seconds, I use 1 usually
plt.close("all")
This question already has answers here:
Matplotlib (pyplot) savefig outputs blank image
(5 answers)
Closed 4 years ago.
EDIT: This question is a duplicate. Original question's link is posted above.
I am using Python to plot a set of values which are showing good on the Python terminal (using Jupyter NoteBook) but when I save it, the saved file when opened shows an empty (completely white) photo. Here's my code:
import matplotlib.pyplot as plt
plt.plot([1,3,4])
plt.show()
plt.savefig('E:/1.png')
You should save the plot before closing it: indeed, plt.show() dislays the plot, and blocks the execution until after you close it; hence when you attempt to save on the next instruction, the plot has been destroyed and can no longer be saved.
import matplotlib.pyplot as plt
plt.plot([1,3,4])
plt.savefig('E:/1.png') # <-- save first
plt.show() # <-- then display
When you execute the show, plt clears the graph. Just invert the execution of show and savefig:
import matplotlib.pyplot as plt
plt.plot([1,3,4])
plt.savefig('E:/1.png')
plt.show()
I think the plt.show() command is "using up" the plot object when you call it. Putting the plt.savefig() command before it should allow it to work.
Also, if you're using Jupyter notebooks you don't even need to use plt.show(), you just need %matplotlib inline somewhere in your notebook to have plots automatically get displayed.
This question already has answers here:
How to set the default color cycle for all subplots with matplotlib?
(3 answers)
How to set default colormap in Matplotlib
(2 answers)
Closed 5 years ago.
I want to use the same colormap/color cycle/palette to every plot in a Jupyter notebook.
With the seaborn package, I can use:
seaborn.set_palette('Set1')
Is there a way to do the same using only matplotlib, without using seaborn?
I know how to define the colormap to each plot separately and I am aware of the predefined style (e.g, ggplot), but I can't find a way to define only the colormap to all the plots at once.
My intention is simplify the code for my students, thus using the intricate code behind set_palette() is not an option.
Edit: as the accepted answer shows, I was confusing colormap with color cycle.
The default colormap in matplotlib is "viridis". This is set at the rcParam "image.cmap".
The default colorcycle can be changed via the "axes.prop_cycle" rcParam.
import matplotlib.pyplot as plt
# to change default colormap
plt.rcParams["image.cmap"] = "Set1"
# to change default color cycle
plt.rcParams['axes.prop_cycle'] = plt.cycler(color=plt.cm.Set1.colors)