Matplotlib title spanning two (or any number of) subplot columns Matplotlib title spanning two (or any number of) subplot columns python python

Matplotlib title spanning two (or any number of) subplot columns


Setting the figure title using fig.suptitle() and the axes (subplot) titles using ax.set_title() is rather straightforward. For setting an intermediate, column spanning title there is indeed no build in option.

One way to solve this issue can be to use a plt.figtext() at the appropriate positions. One needs to account some additional space for that title, e.g. by using fig.subplots_adjust and find appropriate positions of this figtext. In the example below, we use the bounding boxes of the axes the title shall span over to find a centralized horizontal position. The vertical position is a best guess.

import matplotlib.pyplot as pltimport numpy as npx = np.arange(10)y = np.random.rand(10,8)colors=["b", "g", "r", "violet"]fig, axes = plt.subplots(nrows=2, ncols=4, sharex=True, sharey=True, figsize=(8,5)) #set a figure title on topfig.suptitle("Very long figure title over the whole figure extent", fontsize='x-large')# adjust the subplots, i.e. leave more space at the top to accomodate the additional titlesfig.subplots_adjust(top=0.78)     ext = []#loop over the columns (j) and rows(i) to populate subplotsfor j in range(4):    for i in range(2):        axes[i,j].scatter(x, y[:,4*i+j], c=colors[j], s=25)     # each axes in the top row gets its own axes title    axes[0,j].set_title('title {}'.format(j+1))    # save the axes bounding boxes for later use    ext.append([axes[0,j].get_window_extent().x0, axes[0,j].get_window_extent().width ])# this is optional# from the axes bounding boxes calculate the optimal position of the column spanning titleinv = fig.transFigure.inverted()width_left = ext[0][0]+(ext[1][0]+ext[1][1]-ext[0][0])/2.left_center = inv.transform( (width_left, 1) )width_right = ext[2][0]+(ext[3][0]+ext[3][1]-ext[2][0])/2.right_center = inv.transform( (width_right, 1) )# set column spanning title # the first two arguments to figtext are x and y coordinates in the figure system (0 to 1)plt.figtext(left_center[0],0.88,"Left column spanning title", va="center", ha="center", size=15)plt.figtext(right_center[0],0.88,"Right column spanning title", va="center", ha="center", size=15)axes[0,0].set_ylim([0,1])axes[0,0].set_xlim([0,10])plt.show()

enter image description here