after - When to use cla(), clf()or close()for clearing a plot in matplotlib?
savefig subplot (4)
Matplotlib offers there functions:
cla() # Clear axis clf() # Clear figure close() # Close a figure window
The documentation doesn't offer a lot of insight into what the difference between these functions is. When should I use each function and what exactly does it do?
There is just a caveat that I discovered today.
If you have a function that is calling a plot a lot of times you better use
plt.close(fig) instead of
fig.clf() somehow the first does not accumulate in memory. In short if memory is a concern use plt.close(fig) (Although it seems that there are better ways, go to the end of this comment for relevant links).
So the the following script will produce an empty list:
for i in range(5): fig = plot_figure() plt.close(fig) # This returns a list with all figure numbers available print(plt.get_fignums())
Whereas this one will produce a list with five figures on it.
for i in range(5): fig = plot_figure() fig.clf() # This returns a list with all figure numbers available print(plt.get_fignums())
From the documentation above is not clear to me what is the difference between closing a figure and closing a window. Maybe that will clarify.
If you want to try a complete script there you have:
import numpy as np import matplotlib.pyplot as plt x = np.arange(1000) y = np.sin(x) for i in range(5): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(x, y) plt.close(fig) print(plt.get_fignums()) for i in range(5): fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(x, y) fig.clf() print(plt.get_fignums())
If memory is a concern somebody already posted a work-around in SO see: Create a figure that is reference counted
They all do different things, since matplotlib uses a hierarchical order in which a figure window contains a figure which may consist of many axes. Additionally, there are functions from the pyplot interface and there are methods on the
Figure class. I will discuss both cases below.
pyplot is a module that collects a couple of functions that allow matplotlib to be used in a functional manner. I here assume that
pyplot has been imported as
import matplotlib.pyplot as plt.
In this case, there are three different commands that remove stuff:
plt.cla() clears an axes, i.e. the currently active axes in the current figure. It leaves the other axes untouched.
plt.clf() clears the entire current figure with all its axes, but leaves the window opened, such that it may be reused for other plots.
plt.close() closes a window, which will be the current window, if not specified otherwise.
Which functions suits you best depends thus on your use-case.
close() function furthermore allows one to specify which window should be closed. The argument can either be a number or name given to a window when it was created using
figure(number_or_name) or it can be a figure instance
fig obtained, i.e., using
fig = figure(). If no argument is given to
close(), the currently active window will be closed. Furthermore, there is the syntax
close('all'), which closes all figures.
methods of the Figure class
Figure class provides methods for clearing figures.
I'll assume in the following that
fig is an instance of a
fig.clf() clears the entire figure. This call is equivalent to
plt.clf() only if
fig is the current figure.
fig.clear() is a synonym for
Note that even
del fig will not close the associated figure window. As far as I know the only way to close a figure window is using
plt.close(fig) as described above.
plt.cla() means clear current axis
plt.clf() means clear current figure
also, there's plt.gca() (get current axis) and plt.gcf() (get current figure)
Read more here: [Matplotlib, Pyplot, Pylab etc: What's the difference between these and when to use each?](http://queirozf.com/entries/matplotlib-pylab-pyplot-etc-what-s-the-different-between-these
The solution that worked for me when I had huge legend was to use extra empty image layout. In following example I made 4 rows and at the bottom I plot image with offset for legend (bbox_to_anchor) at the top it does not get cut.
f = plt.figure() ax = f.add_subplot(414) lgd = ax.legend(loc='upper left', bbox_to_anchor=(0, 4), mode="expand", borderaxespad=0.3) ax.autoscale_view() plt.savefig(fig_name, format='svg', dpi=1200, bbox_extra_artists=(lgd,), bbox_inches='tight')