I am creating a large array of subplots and I want to turn off axes for all the subplots.
Currently I am achieving this by
fig, ax = plt.subplots(7, len(clusters))
fig.subplots_adjust(wspace=0, top=1.0, bottom=0.5, left=0, right=1.0)
for x in ax.ravel():
x.axis("off")
but looping over the subplots to turn of the axes individually is ugly.
Is there a way to tell subplots to turn od axes at creation time
or some setting on Figure or pyplot that turns axes off globally.
pyplot.axis('off') turns off axes just on the last subplot.
I agree with #tcaswell that you should probably just use what you're already using. Another option to use it as a function is to use numpy.vectorize():
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(7, len(clusters))
np.vectorize(lambda ax:ax.axis('off'))(ax)
or, if you need to invoke it multiple times, by assigning the vectorized function to a variable:
axoff_fun = np.vectorize(lambda ax:ax.axis('off'))
# ... stuff here ...
fig, ax = plt.subplots(7, len(clusters))
axoff_fun(ax)
Again, note that this is the same thing that #tcaswell suggested, in a fancier setting (only slower, probably). And it's essentially the same thing you're using now.
However, if you insist on doing it some other way (i.e. you are a special kind of lazy), you can set matplotlib.rcParams once, and then every subsequent axes will automatically be off. There's probably an easier way to emulate axis('off'), but here's how I've succeeded:
import matplotlib as mpl
# before
mpl.pyplot.figure()
mpl.pyplot.plot([1,3,5],[4,6,5])
# kill axis in rcParams
mpl.rc('axes.spines',top=False,bottom=False,left=False,right=False);
mpl.rc('axes',facecolor=(1,1,1,0),edgecolor=(1,1,1,0));
mpl.rc(('xtick','ytick'),color=(1,1,1,0));
# after
mpl.pyplot.figure()
mpl.pyplot.plot([1,3,5],[4,6,5])
Result before/after:
Hopefully there aren't any surprises which I forgot to override, but that would become clear quite quickly in an actual application anyway.
Related
Matplotlib offers these functions:
cla() # Clear axis
clf() # Clear figure
close() # Close a figure window
When should I use each function and what exactly does it do?
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 interface
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:
See matplotlib.pyplot Functions:
plt.cla() clears an axis, i.e. the currently active axis 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.
The 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., usingfig = 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
Additionally, the Figure class provides methods for clearing figures.
I'll assume in the following that fig is an instance of a Figure:
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 fig.clf()
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.
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
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?
The following example code generates a simple plot, then saves it to 'fig1.pdf', then displays it, then saves it again to 'fig2.pdf'. The first image looks as expected, but the second one is blank (contains a white square). What's actually going on here? The line plt.show() apparently messes something up, but I can't figure out what/how!
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x,y)
plt.savefig('fig1.pdf')
plt.show()
plt.savefig('fig2.pdf')
If you want to save the figure after displaying it, you'll need to hold on to the figure instance. The reason that plt.savefig doesn't work after calling show is that the current figure has been reset.
pyplot keeps track of which figures, axes, etc are "current" (i.e. have not yet been displayed with show) behind-the-scenes. gcf and gca get the current figure and current axes instances, respectively. plt.savefig (and essentially any other pyplot method) just does plt.gcf().savefig(...). In other words, get the current figure instance and call its savefig method. Similarly plt.plot basically does plt.gca().plot(...).
After show is called, the list of "current" figures and axes is empty.
In general, you're better off directly using the figure and axes instances to plot/save/show/etc, rather than using plt.plot, etc, to implicitly get the current figure/axes and plot on it. There's nothing wrong with using pyplot for everything (especially interactively), but it makes it easier to shoot yourself in the foot.
Use pyplot for plt.show() and to generate a figure and an axes object(s), but then use the figure or axes methods directly. (e.g. ax.plot(x, y) instead of plt.plot(x, y), etc) The main advantage of this is that it's explicit. You know what objects you're plotting on, and don't have to reason about what the pyplot state-machine does (though it's not that hard to understand the state-machine interface, either).
As an example of the "recommended" way of doing things, do something like:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
fig, ax = plt.subplots()
ax.plot(x, y)
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')
If you'd rather use the pyplot interface for everything, then just grab the figure instance before you call show. For example:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x, y)
fig = plt.gcf()
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')
pyplot.show blocks and destroys the plot upon closing. You can use
plt.show(block=False)
after which the save to fig2.pdf will work or you can plot it again before saving
plt.plot(x,y)
plt.savefig('fig2.pdf')
I had to run plt.cla() and plt.clf() before plotting the second one. Clear current axes and clear current plot, respectively.
If you just want to see the figure before saving, you can call
plt.ion()
before plotting, which starts interactive mode, and shows all figures as they are drawn. This mostly removes the need to call plt.show(). You no longer need to close the figures to continue.
To disable interactive mode again, call plt.ioff().
The following example code generates a simple plot, then saves it to 'fig1.pdf', then displays it, then saves it again to 'fig2.pdf'. The first image looks as expected, but the second one is blank (contains a white square). What's actually going on here? The line plt.show() apparently messes something up, but I can't figure out what/how!
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x,y)
plt.savefig('fig1.pdf')
plt.show()
plt.savefig('fig2.pdf')
If you want to save the figure after displaying it, you'll need to hold on to the figure instance. The reason that plt.savefig doesn't work after calling show is that the current figure has been reset.
pyplot keeps track of which figures, axes, etc are "current" (i.e. have not yet been displayed with show) behind-the-scenes. gcf and gca get the current figure and current axes instances, respectively. plt.savefig (and essentially any other pyplot method) just does plt.gcf().savefig(...). In other words, get the current figure instance and call its savefig method. Similarly plt.plot basically does plt.gca().plot(...).
After show is called, the list of "current" figures and axes is empty.
In general, you're better off directly using the figure and axes instances to plot/save/show/etc, rather than using plt.plot, etc, to implicitly get the current figure/axes and plot on it. There's nothing wrong with using pyplot for everything (especially interactively), but it makes it easier to shoot yourself in the foot.
Use pyplot for plt.show() and to generate a figure and an axes object(s), but then use the figure or axes methods directly. (e.g. ax.plot(x, y) instead of plt.plot(x, y), etc) The main advantage of this is that it's explicit. You know what objects you're plotting on, and don't have to reason about what the pyplot state-machine does (though it's not that hard to understand the state-machine interface, either).
As an example of the "recommended" way of doing things, do something like:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
fig, ax = plt.subplots()
ax.plot(x, y)
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')
If you'd rather use the pyplot interface for everything, then just grab the figure instance before you call show. For example:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x, y)
fig = plt.gcf()
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')
pyplot.show blocks and destroys the plot upon closing. You can use
plt.show(block=False)
after which the save to fig2.pdf will work or you can plot it again before saving
plt.plot(x,y)
plt.savefig('fig2.pdf')
I had to run plt.cla() and plt.clf() before plotting the second one. Clear current axes and clear current plot, respectively.
If you just want to see the figure before saving, you can call
plt.ion()
before plotting, which starts interactive mode, and shows all figures as they are drawn. This mostly removes the need to call plt.show(). You no longer need to close the figures to continue.
To disable interactive mode again, call plt.ioff().
The following example code generates a simple plot, then saves it to 'fig1.pdf', then displays it, then saves it again to 'fig2.pdf'. The first image looks as expected, but the second one is blank (contains a white square). What's actually going on here? The line plt.show() apparently messes something up, but I can't figure out what/how!
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x,y)
plt.savefig('fig1.pdf')
plt.show()
plt.savefig('fig2.pdf')
If you want to save the figure after displaying it, you'll need to hold on to the figure instance. The reason that plt.savefig doesn't work after calling show is that the current figure has been reset.
pyplot keeps track of which figures, axes, etc are "current" (i.e. have not yet been displayed with show) behind-the-scenes. gcf and gca get the current figure and current axes instances, respectively. plt.savefig (and essentially any other pyplot method) just does plt.gcf().savefig(...). In other words, get the current figure instance and call its savefig method. Similarly plt.plot basically does plt.gca().plot(...).
After show is called, the list of "current" figures and axes is empty.
In general, you're better off directly using the figure and axes instances to plot/save/show/etc, rather than using plt.plot, etc, to implicitly get the current figure/axes and plot on it. There's nothing wrong with using pyplot for everything (especially interactively), but it makes it easier to shoot yourself in the foot.
Use pyplot for plt.show() and to generate a figure and an axes object(s), but then use the figure or axes methods directly. (e.g. ax.plot(x, y) instead of plt.plot(x, y), etc) The main advantage of this is that it's explicit. You know what objects you're plotting on, and don't have to reason about what the pyplot state-machine does (though it's not that hard to understand the state-machine interface, either).
As an example of the "recommended" way of doing things, do something like:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
fig, ax = plt.subplots()
ax.plot(x, y)
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')
If you'd rather use the pyplot interface for everything, then just grab the figure instance before you call show. For example:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x, y)
fig = plt.gcf()
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')
pyplot.show blocks and destroys the plot upon closing. You can use
plt.show(block=False)
after which the save to fig2.pdf will work or you can plot it again before saving
plt.plot(x,y)
plt.savefig('fig2.pdf')
I had to run plt.cla() and plt.clf() before plotting the second one. Clear current axes and clear current plot, respectively.
If you just want to see the figure before saving, you can call
plt.ion()
before plotting, which starts interactive mode, and shows all figures as they are drawn. This mostly removes the need to call plt.show(). You no longer need to close the figures to continue.
To disable interactive mode again, call plt.ioff().
I am righteously confused with the coding paradigms offered by matplotlib. I am using code like this below to plot some data:
fig=plt.figure(figsize=fig_size) # plt=pyplot defined above
axes1 = fig.add_subplot(111)
axes1.plot(temp, depth, 'k-')
axes1.set_ylim(-600,0)
axes1.set_ylabel(r'Depth $(m)$')
axes1.set_xlim(0,80)
axes1.set_xlabel(r'Temperature (\textcelsius)')
axes1.set_xticks(np.arange(0,100,20))
axes1.grid(True)
plt.savefig(savedir + 'plot.svg', transparent=True)
I'd rather use mpl's object-oriented style than the pylab convenience functions. So question is if I only want to plot one curve, non-interactively, am I using the right figure creation style? (lines 1 & 2). It seems like a lot of separate calls are needed to format the axis labels and so on.
What you're doing looks fine. (And I agree, it's much cleaner to only use pyplot for figure creation and use the OO API for everything else.)
If you'd prefer to make the figure and axes in one call, use plt.subplots.
Also, I find it's a bit cleaner to use fig.savefig instead of plt.savefig. It won't matter in this case, but that way you avoid having to worry about which figure is "active" in the state-machine interface.
For one last thing, you could set the x and y limits with a single call to axes1.axis(...). This is purely a matter of preference. set_xlim and set_ylim are arguably a more readable way of doing it.
The "setters" and "getters" are annoying, but date from when python didn't have properties, if I recall correctly. They've been kept as the main methods partly for backwards compatibility, and partly so that "matlab-isms" like plt.setp are easier to write. In fact, if you wanted you could do
plt.setp(ax, xlabel='Xlabel', ylabel='Ylabel', xticks=range(0, 100, 20))
This avoids having to do three separate calls to set the xlabel, ylabel, and xticks. However, I personally tend to avoid it. I find it's better to be slightly more verbose in most cases. If you find it cleaner or more convenient, though, there's nothing wrong with using setp.
As an example of how I'd write it:
import matplotlib.pyplot as plt
import numpy as np
depth = np.linspace(-600, 0, 30)
temp = (4 * np.random.random(depth.size)).cumsum()
fig, ax = plt.subplots()
ax.plot(temp, depth, 'k-')
ax.axis([0, 80, -600, 0])
ax.set_ylabel(r'Depth $(m)$')
ax.set_xlabel(r'Temperature $(^{\circ}C)$')
ax.set_xticks(np.arange(0, 100, 20))
ax.grid(True)
fig.savefig('plot.svg', transparent=True)
plt.show()