tomka tomka - 2 months ago 8
Python Question

Using pyplot to create grids of plots

I am new to python and having some difficulties with plotting using

pyplot
. My goal is to plot a grid of plots in-line (
%pylab inline
) in Juypter Notebook.

I programmed a function
plot_CV
which plots cross-validation erorr over the degree of polynomial of some x where across plots the degree of penalization (lambda) is supposed to vary. Ultimately there are 10 elements in lambda and they are controlled by the first argument in
plot_CV
. So

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax1 = plot_CV(1,CV_ve=CV_ve)


Gives

enter image description here

Now I think I have to use
add_subplot
to create a grid of plots as in

fig = plt.figure()
ax1 = fig.add_subplot(2,2,1)
ax1 = plot_CV(1,CV_ve=CV_ve)
ax2 = fig.add_subplot(2,2,2)
ax2 = plot_CV(2,CV_ve=CV_ve)
ax3 = fig.add_subplot(2,2,3)
ax3 = plot_CV(3,CV_ve=CV_ve)
ax4 = fig.add_subplot(2,2,4)
ax4 = plot_CV(4,CV_ve=CV_ve)
plt.show()


enter image description here

If I continue this, however, then the plots get smaller and smaller and start to overlap on the x and y labels. Here a picture with a 3 by 3 plot.

enter image description here

Is there a way to space the plots evenly, so that they do not overlap and make better use of the horizontal and vertical in-line space in Jupyter Notebook? To illustrate this point here a screenshot from jupyter:

enter image description here

Final note: I still need to add a title or annotation with the current level of lambda used in
plot_CV
.




Edit: Using the tight layout as suggested, gives:

enter image description here




Edit 2: Using the
fig.set_figheight
and
fig.set_figwidth
I could finally use the full length and heigth available.

enter image description here

Answer

A first suggestion to you problem would be taking a look at the "Tight Layout guide" for matplotlib.

They have an example that looks visually very similar to your situation. As well they have examples and suggestions for taking into consideration axis labels and plot titles.

Further more you can control the over all figure size by using Figure from the matplotlib.figure class.

Figure(figsize = (x,y))

figsize: x,y (inches)

EDIT:

Here is an example that I pulled from the matplotlib website and added in the:

fig.set_figheight(15) fig.set_figwidth(15)

import matplotlib.pyplot as plt

plt.rcParams['savefig.facecolor'] = "0.8"

def example_plot(ax, fontsize=12):
     ax.plot([1, 2])
     ax.locator_params(nbins=3)
     ax.set_xlabel('x-label', fontsize=fontsize)
     ax.set_ylabel('y-label', fontsize=fontsize)
     ax.set_title('Title', fontsize=fontsize)

plt.close('all')
fig = plt.figure()

fig.set_figheight(15)
fig.set_figwidth(15)


ax1 = plt.subplot2grid((3, 3), (0, 0))
ax2 = plt.subplot2grid((3, 3), (0, 1), colspan=2)
ax3 = plt.subplot2grid((3, 3), (1, 0), colspan=2, rowspan=2)
ax4 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)

example_plot(ax1)
example_plot(ax2)
example_plot(ax3)
example_plot(ax4)

plt.tight_layout()

You can achieve padding of your subplots by using tight_layout this way:

plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)

That way you can keep your subplots from crowding each other even further.

Have a good one!