Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 249
tomka Avatar asked Jan 06 '23 07:01

tomka


1 Answers

The first suggestion to your 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.

Furthermore you can control the overall 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)

example:

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!

like image 106
Kyle Swanson Avatar answered Jan 13 '23 02:01

Kyle Swanson