Row titles for matplotlib subplot - python

In matplotlib, Is it possible to set a a separate title for each row of subplots in addition to the title set for the entire figure and the title set for each individual plot? This would correspond to the orange text in the figure below.
If not, how would you get around this problem? Create a separate column of empty subplots to the left and fill them with the orange text?
I am aware that it is possible to manually position each single title using text() or annotate(), but that usually requires a lot of tweaking and I have many subplots. Is there a smoother solution?

New in matplotlib 3.4.0
Row titles can now be implemented as subfigure suptitles:
The new subfigure feature allows creating virtual figures within figures with localized artists (e.g., colorbars and suptitles) that only pertain to each subfigure.
See how to plot subfigures for further details.
How to reproduce OP's reference figure:
Either Figure.subfigures (most straightforward)
Create 3x1 fig.subfigures where each subfig gets its own 1x3 subfig.subplots and subfig.suptitle:
fig = plt.figure(constrained_layout=True)
fig.suptitle('Figure title')
# create 3x1 subfigs
subfigs = fig.subfigures(nrows=3, ncols=1)
for row, subfig in enumerate(subfigs):
subfig.suptitle(f'Subfigure title {row}')
# create 1x3 subplots per subfig
axs = subfig.subplots(nrows=1, ncols=3)
for col, ax in enumerate(axs):
ax.plot()
ax.set_title(f'Plot title {col}')
Or Figure.add_subfigure (onto existing subplots)
If you already have 3x1 plt.subplots, then add_subfigure into the underlying gridspec. Again each subfig will get its own 1x3 subfig.subplots and subfig.suptitle:
# create 3x1 subplots
fig, axs = plt.subplots(nrows=3, ncols=1, constrained_layout=True)
fig.suptitle('Figure title')
# clear subplots
for ax in axs:
ax.remove()
# add subfigure per subplot
gridspec = axs[0].get_subplotspec().get_gridspec()
subfigs = [fig.add_subfigure(gs) for gs in gridspec]
for row, subfig in enumerate(subfigs):
subfig.suptitle(f'Subfigure title {row}')
# create 1x3 subplots per subfig
axs = subfig.subplots(nrows=1, ncols=3)
for col, ax in enumerate(axs):
ax.plot()
ax.set_title(f'Plot title {col}')
Output of either example (after some styling):

An idea is to create three "big subplots", to give each of them a title, and make them invisible. On the top of that you can create your matrix of smaller subplots.
This solution is entirely based on this post, except that more attention has been paid to actually removing the background subplot.
import matplotlib.pyplot as plt
fig, big_axes = plt.subplots( figsize=(15.0, 15.0) , nrows=3, ncols=1, sharey=True)
for row, big_ax in enumerate(big_axes, start=1):
big_ax.set_title("Subplot row %s \n" % row, fontsize=16)
# Turn off axis lines and ticks of the big subplot
# obs alpha is 0 in RGBA string!
big_ax.tick_params(labelcolor=(1.,1.,1., 0.0), top='off', bottom='off', left='off', right='off')
# removes the white frame
big_ax._frameon = False
for i in range(1,10):
ax = fig.add_subplot(3,3,i)
ax.set_title('Plot title ' + str(i))
fig.set_facecolor('w')
plt.tight_layout()
plt.show()

It is better to firstly plot your real subplots and then plot empty subplots above them, thus you will have a more precise title align. And to do it precisely we need plt.GridSpec() (link).
It is best seen in columns subtitles:
# modified code of #snake_chrmer
fig, big_axes = plt.subplots(figsize=(9, 3) , nrows=1, ncols=3, sharey=True)
for title, big_ax in zip(['First', 'Second', 'Third'], big_axes):
big_ax.set_title(f'{title}\n', fontweight='semibold')
big_ax.set_frame_on(False)
big_ax.axis('off')
for i in range(1, 7):
ax = fig.add_subplot(1,6,i)
ax.set_title('Plot title ' + str(i))
fig.set_facecolor('w')
plt.tight_layout()
plt.show()
# my solition
import matplotlib.pyplot as plt
from matplotlib.gridspec import SubplotSpec
def create_subtitle(fig: plt.Figure, grid: SubplotSpec, title: str):
"Sign sets of subplots with title"
row = fig.add_subplot(grid)
# the '\n' is important
row.set_title(f'{title}\n', fontweight='semibold')
# hide subplot
row.set_frame_on(False)
row.axis('off')
rows = 1
cols = 6
fig, axs = plt.subplots(rows, cols, figsize=(9, 3))
for i, ax in enumerate(axs.flatten()):
ax.set_title(f'Plot title {i}')
grid = plt.GridSpec(rows, cols)
create_subtitle(fig, grid[0, 0:2], 'First')
create_subtitle(fig, grid[0, 2:4], 'Second')
create_subtitle(fig, grid[0, 4:6], 'Third')
fig.tight_layout()
fig.set_facecolor('w')
# original problem
rows = 3
cols = 3
fig, axs = plt.subplots(rows, cols, figsize=(9, 9))
for i, ax in enumerate(axs.flatten()):
ax.set_title(f'Plot title {i}')
grid = plt.GridSpec(rows, cols)
create_subtitle(fig, grid[0, ::], 'First')
create_subtitle(fig, grid[1, ::], 'Second')
create_subtitle(fig, grid[2, ::], 'Third')
fig.tight_layout()
fig.set_facecolor('w')
UPD
It is more logical and comprehensible to create subgrid for a set of subplots just to title them. The subgrig gives a wast space for modifications:
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
rows = 1
cols = 3
fig = plt.figure(figsize=(9, 3))
# grid for pairs of subplots
grid = plt.GridSpec(rows, cols)
for i in range(rows * cols):
# create fake subplot just to title pair of subplots
fake = fig.add_subplot(grid[i])
# '\n' is important
fake.set_title(f'Fake #{i}\n', fontweight='semibold', size=14)
fake.set_axis_off()
# create subgrid for two subplots without space between them
# <https://matplotlib.org/2.0.2/users/gridspec.html>
gs = gridspec.GridSpecFromSubplotSpec(1, 2, subplot_spec=grid[i], wspace=0)
# real subplot #1
ax = fig.add_subplot(gs[0])
ax.set_title(f'Real {i}1')
# hide ticks and labels
ax.tick_params(left=False, labelleft=False, labelbottom=False, bottom=False)
# real subplot #2
ax = fig.add_subplot(gs[1], sharey=ax)
ax.set_title(f'Real {i}2')
# hide ticks and labels
ax.tick_params(left=False, labelleft=False, labelbottom=False, bottom=False)
fig.patch.set_facecolor('white')
fig.suptitle('SUPERTITLE', fontweight='bold', size=16)
fig.tight_layout()
Original problem:
rows = 3
cols = 1
fig = plt.figure(figsize=(9, 9))
# grid for pairs of subplots
grid = plt.GridSpec(rows, cols)
for i in range(rows * cols):
# create fake subplot just to title set of subplots
fake = fig.add_subplot(grid[i])
# '\n' is important
fake.set_title(f'Fake #{i}\n', fontweight='semibold', size=14)
fake.set_axis_off()
# create subgrid for two subplots without space between them
# <https://matplotlib.org/2.0.2/users/gridspec.html>
gs = gridspec.GridSpecFromSubplotSpec(1, 3, subplot_spec=grid[i])
# real subplot #1
ax = fig.add_subplot(gs[0])
ax.set_title(f'Real {i}1')
# real subplot #2
ax = fig.add_subplot(gs[1], sharey=ax)
ax.set_title(f'Real {i}2')
# real subplot #3
ax = fig.add_subplot(gs[2], sharey=ax)
ax.set_title(f'Real {i}3')
fig.patch.set_facecolor('white')
fig.suptitle('SUPERTITLE', fontweight='bold', size=16)
fig.tight_layout()

Another easy cheat is to give the title of the middle column as subplot row XX\n\nPlot title No.YY

Related

Subplotting subplots

I am creating two plots using matplotlib, each of them is a subplot showing two metrics on the same axis.
I'm trying to run them so they show as two charts but in one graphic, so that when I save the graphic I see both plots. At the moment, running the second plot overwrites the first in memory so I can only ever save the second.
How can I plot them together?
My code is below.
plot1 = plt.figure()
fig,ax1 = plt.subplots()
ax1.plot(dfSat['time'],dfSat['wind_at_altitude'], 'b-', label = "speed", linewidth = 5.0)
plt.title('Wind Speeds - Saturday - {}'.format(windloc))
plt.xlabel('Time of day')
plt.ylabel('Wind speed (mph)')
ax1.plot(dfSat['time'],dfSat['gust_at_altitude'], 'r-', label = "gust", linewidth = 5.0)
plt.legend(loc="upper right")
ax1.text(0.05, 0.95, calcmeassat, transform=ax1.transAxes, fontsize=30,
verticalalignment='top')
plt.ylim((0,100))
plot2 = plt.figure()
fig,ax2 = plt.subplots()
ax2.plot(dfSun['time'],dfSun['wind_at_altitude'], 'b-', label = "speed", linewidth = 5.0)
plt.title('Wind Speeds - Sunday - {}'.format(windloc))
plt.xlabel('Time of day')
plt.ylabel('Wind speed (mph)')
ax2.plot(dfSun['time'],dfSun['gust_at_altitude'], 'r-', label = "gust", linewidth = 5.0)
plt.legend(loc="upper right")
ax2.text(0.05, 0.95, calcmeassun, transform=ax2.transAxes, fontsize=30,
verticalalignment='top')
plt.ylim((0,100))
As mentioned, in your case you only need one level of subplots, e.g., nrows=1, ncols=2.
However, in matplotlib 3.4+ there is such a thing as "subplotting subplots" called subfigures, which makes it easier to implement nested layouts, e.g.:
How to create row titles for subplots
How to share colorbars within some subplots
How to share xlabels within some subplots
Subplots
For your simpler use case, create 1x2 subplots with ax1 on the left and ax2 on the right:
# create 1x2 subplots
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(16, 4))
# plot saturdays on the left
dfSat.plot(ax=ax1, x='date', y='temp_min')
dfSat.plot(ax=ax1, x='date', y='temp_max')
ax1.set_ylim(-20, 50)
ax1.set_title('Saturdays')
# plot sundays on the right
dfSun.plot(ax=ax2, x='date', y='temp_min')
dfSun.plot(ax=ax2, x='date', y='temp_max')
ax2.set_ylim(-20, 50)
ax2.set_title('Sundays')
Subfigures
Say you want something more complicated like having the left side show 2012 with its own suptitle and right side to show 2015 with its own suptitle.
Create 1x2 subfigures (left subfig_l and right subfig_r) with 2x1 subplots on the left (top ax_lt and bottom ax_lb) and 2x1 subplots on the right (top ax_rt and bottom ax_rb):
# create 1x2 subfigures
fig = plt.figure(constrained_layout=True, figsize=(12, 5))
(subfig_l, subfig_r) = fig.subfigures(nrows=1, ncols=2, wspace=0.07)
# create top/box axes in left subfig
(ax_lt, ax_lb) = subfig_l.subplots(nrows=2, ncols=1)
# plot 2012 saturdays on left-top axes
dfSat12 = dfSat.loc[dfSat['date'].dt.year.eq(2012)]
dfSat12.plot(ax=ax_lt, x='date', y='temp_min')
dfSat12.plot(ax=ax_lt, x='date', y='temp_max')
ax_lt.set_ylim(-20, 50)
ax_lt.set_ylabel('Saturdays')
# plot 2012 sundays on left-top axes
dfSun12 = dfSun.loc[dfSun['date'].dt.year.eq(2012)]
dfSun12.plot(ax=ax_lb, x='date', y='temp_min')
dfSun12.plot(ax=ax_lb, x='date', y='temp_max')
ax_lb.set_ylim(-20, 50)
ax_lb.set_ylabel('Sundays')
# set suptitle for left subfig
subfig_l.suptitle('2012', size='x-large', weight='bold')
# create top/box axes in right subfig
(ax_rt, ax_rb) = subfig_r.subplots(nrows=2, ncols=1)
# plot 2015 saturdays on left-top axes
dfSat15 = dfSat.loc[dfSat['date'].dt.year.eq(2015)]
dfSat15.plot(ax=ax_rt, x='date', y='temp_min')
dfSat15.plot(ax=ax_rt, x='date', y='temp_max')
ax_rt.set_ylim(-20, 50)
ax_rt.set_ylabel('Saturdays')
# plot 2015 sundays on left-top axes
dfSun15 = dfSun.loc[dfSun['date'].dt.year.eq(2015)]
dfSun15.plot(ax=ax_rb, x='date', y='temp_min')
dfSun15.plot(ax=ax_rb, x='date', y='temp_max')
ax_rb.set_ylim(-20, 50)
ax_rb.set_ylabel('Sundays')
# set suptitle for right subfig
subfig_r.suptitle('2015', size='x-large', weight='bold')
Sample data for reference:
import pandas as pd
from vega_datasets import data
df = data.seattle_weather()
df['date'] = pd.to_datetime(df['date'])
dfSat = df.loc[df['date'].dt.weekday.eq(5)]
dfSun = df.loc[df['date'].dt.weekday.eq(6)]
It doesn't work like that. Subplots are what they are called; plots inside a main plot.
That means if you need two subplots; then you need one plot containing two subplots in it.
# figure object NOT plot object
# useful when you want only one plot NO subplots
fig = plt.figure()
# 2 subplots inside 1 plot
# 1 row, 2 columns
fig, [ax1, ax2] = plt.subplots(1, 2)
# then call plotting method on each axis object to
# create plot on that subplot
sns.histplot(...., ax=ax1)
sns.violinplot(..., ax=ax2)
# or using matplotlib like this
ax1.plot()
ax2.plot()
Learn more about subplots

Arrange matplotlib subplots in skewed grid

Using matplotlib, I'd like to display multiple subplots on a grid that has a different number of columns per row, where each subplot has roughly the same size, and the subplots are arranged such that they are more or less centered, like this:
It's a fairly simple matter to create a grid that has the 2, 3, 2 pattern with gridspec, but the problem there is that gridspec, unsurprisingly, aligns them to a grid, so the plots in the rows with 2 plots in them are wider:
Here's the code to generate that:
from matplotlib import gridspec
from matplotlib import pyplot as plt
fig = plt.figure()
arrangement = (2, 3, 2)
nrows = len(arrangement)
gs = gridspec.GridSpec(nrows, 1)
ax_specs = []
for r, ncols in enumerate(arrangement):
gs_row = gridspec.GridSpecFromSubplotSpec(1, ncols, subplot_spec=gs[r])
for col in range(ncols):
ax = plt.Subplot(fig, gs_row[col])
fig.add_subplot(ax)
for i, ax in enumerate(fig.axes):
ax.text(0.5, 0.5, "Axis: {}".format(i), fontweight='bold',
va="center", ha="center")
ax.tick_params(axis='both', bottom='off', top='off', left='off',
right='off', labelbottom='off', labelleft='off')
plt.tight_layout()
I know that I can set up a bunch of subplots and tweak their arrangement by working out the geometry of it, but I think it could get a bit complicated, so I was hoping that there might be a simpler method available.
I should note that even though I'm using a (2, 3, 2) arrangement as my example, I'd like to do this for arbitrary collections, not just this one.
The idea is usually to find the common denominator between the subplots, i.e. the largest subplot that the desired grid can be composed of, and span all subplots over several of those such that the desired layout is achieved.
Here you have 3 rows and 6 columns and each subplot spans 1 row and two columns, just that the subplots in the first row span subplot positions 1/2 and 3/4, while in the second row they span positions 0/1, 2/3, 4/5.
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(3, 6)
ax1a = plt.subplot(gs[0, 1:3])
ax1b = plt.subplot(gs[0, 3:5])
ax2a = plt.subplot(gs[1, :2])
ax2b = plt.subplot(gs[1, 2:4])
ax2c = plt.subplot(gs[1, 4:])
ax3a = plt.subplot(gs[2, 1:3])
ax3b = plt.subplot(gs[2, 3:5])
for i, ax in enumerate(plt.gcf().axes):
ax.text(0.5, 0.5, "Axis: {}".format(i), fontweight='bold',
va="center", ha="center")
ax.tick_params(axis='both', bottom='off', top='off', left='off',
right='off', labelbottom='off', labelleft='off')
plt.tight_layout()
plt.show()

How add plot to subplot matplotlib [duplicate]

This question already has answers here:
How to plot in multiple subplots
(12 answers)
Closed 8 months ago.
I have plots like this
fig = plt.figure()
desire_salary = (df[(df['inc'] <= int(salary_people))])
print desire_salary
# Create the pivot_table
result = desire_salary.pivot_table('city', 'cult', aggfunc='count')
# plot it in a separate step. this returns the matplotlib axes
ax = result.plot(kind='bar', alpha=0.75, rot=0, label="Presence / Absence of cultural centre")
ax.set_xlabel("Cultural centre")
ax.set_ylabel("Frequency")
ax.set_title('The relationship between the wage level and the presence of the cultural center')
plt.show()
I want to add this to subplot. I try
fig, ax = plt.subplots(2, 3)
...
ax = result.add_subplot()
but it returns
AttributeError: 'Series' object has no attribute 'add_subplot'`. How can I check this error?
matplotlib.pyplot has the concept of the current figure and the current axes. All plotting commands apply to the current axes.
import matplotlib.pyplot as plt
fig, axarr = plt.subplots(2, 3) # 6 axes, returned as a 2-d array
#1 The first subplot
plt.sca(axarr[0, 0]) # set the current axes instance to the top left
# plot your data
result.plot(kind='bar', alpha=0.75, rot=0, label="Presence / Absence of cultural centre")
#2 The second subplot
plt.sca(axarr[0, 1]) # set the current axes instance
# plot your data
#3 The third subplot
plt.sca(axarr[0, 2]) # set the current axes instance
# plot your data
Demo:
The source code,
import matplotlib.pyplot as plt
fig, axarr = plt.subplots(2, 3, sharex=True, sharey=True) # 6 axes, returned as a 2-d array
for i in range(2):
for j in range(3):
plt.sca(axarr[i, j]) # set the current axes instance
axarr[i, j].plot(i, j, 'ro', markersize=10) # plot
axarr[i, j].set_xlabel(str(tuple([i, j]))) # set x label
axarr[i, j].get_xaxis().set_ticks([]) # hidden x axis text
axarr[i, j].get_yaxis().set_ticks([]) # hidden y axis text
plt.show()
result is of pandas.Series type, which doesn't have add_subplot() method.
use fig.add_subplot(...) instead
Here is an example (using seaborn module):
labels = df.columns.values
fig, axes = plt.subplots(nrows = 3, ncols = 4, gridspec_kw = dict(hspace=0.3),figsize=(12,9), sharex = True, sharey=True)
targets = zip(labels, axes.flatten())
for i, (col,ax) in enumerate(targets):
sns.boxplot(data=df, ax=ax, color='green', x=df.index.month, y=col)
You can use pandas plots instead of seaborn

Fitting 3 subplots on the same figure

I am trying to plot 3 subplots on the same figure and for some reason the code I have is not working. The first two appear on the same figure, but the last one doesn't. Can someone help me out:
fig = plt.figure(0, figsize = (12,10))
fig.add_subplot(221)
bike_gender.plot(kind='bar',title='Trip Duration by Gender', figsize= (9,7))
bar_plot.set_ylabel('Trip duration')
bar_plot.set_xlabel('Gender')
bar_plot.xaxis.set_ticklabels(['Men', 'Women', 'Unknown'])
bar_plot.text (0, 400000, 'Men = 647,466', bbox=dict(facecolor='red', alpha=0.5))
bar_plot.text (1, 400000, 'Women = 202,136', bbox=dict(facecolor='red', alpha=0.5))
bar_plot.text (2, 400000, 'Unknown = 119,240', bbox=dict(facecolor='red', alpha=0.5))
fig.add_subplot(222)
labels = 'Subscriber \n (849,778)', 'Customer \n (119,064)'
pie_chart = bike_user.plot(kind='pie', title= 'Breakdown of usertype', labels = labels, autopct='%1.1f%%', figsize=(9,7))
fig.add_subplot(212)
frequencies.plot(kind='bar',color=['blue','yellow','green'], figsize=(12, 4), stacked=True)
plt.show()
An alternative way is to use gridspec
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
fig = plt.figure()
data = pd.DataFrame(np.random.rand(10,2))
gs = gridspec.GridSpec(2,2)
ax1=fig.add_subplot(gs[0,0])
ax2=fig.add_subplot(gs[0,1])
ax3=fig.add_subplot(gs[1,:])
data.plot(ax = ax1)
data.plot(ax = ax2)
data.plot(ax = ax3)
plt.show()
The last plot should actually appears on the figure, but behind the second one.
It's because your third subplot is in a grid whose shape differs from what you already use. You first 2 plots are on a 2x2 grid (add_subplot(22.)) while the last one is on a 2x1 grid (add_subplot(21.)).
As a quick fix, you can try for your last plot:
fig.add_subplot(223)
And it should work.
However, you seems to want to make plot with pandas and display them in a specific axes of a figure with subplots. To do so you should use:
fig, ax = plt.subplots(2,2, figsize=(12,10))
bike_gender.plot(kind="bar", ax=ax[0], title='Trip Duration by Gender')
bike_user.plot(kind='pie', ax=ax[1], title= 'Breakdown of usertype')
frequencies.plot(kind='bar', ax=ax[2], color=['blue','yellow','green'], stacked=True)
HTH

How to add a title to each subplot

I have one figure which contains many subplots.
fig = plt.figure(num=None, figsize=(26, 12), dpi=80, facecolor='w', edgecolor='k')
fig.canvas.set_window_title('Window Title')
# Returns the Axes instance
ax = fig.add_subplot(311)
ax2 = fig.add_subplot(312)
ax3 = fig.add_subplot(313)
How do I add titles to the subplots?
fig.suptitle adds a title to all graphs and although ax.set_title() exists, the latter does not add any title to my subplots.
Thank you for your help.
Edit:
Corrected typo about set_title(). Thanks Rutger Kassies
ax.title.set_text('My Plot Title') seems to work too.
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax4 = fig.add_subplot(224)
ax1.title.set_text('First Plot')
ax2.title.set_text('Second Plot')
ax3.title.set_text('Third Plot')
ax4.title.set_text('Fourth Plot')
plt.show()
ax.set_title() should set the titles for separate subplots:
import matplotlib.pyplot as plt
if __name__ == "__main__":
data = [1, 2, 3, 4, 5]
fig = plt.figure()
fig.suptitle("Title for whole figure", fontsize=16)
ax = plt.subplot("211")
ax.set_title("Title for first plot")
ax.plot(data)
ax = plt.subplot("212")
ax.set_title("Title for second plot")
ax.plot(data)
plt.show()
Can you check if this code works for you? Maybe something overwrites them later?
A shorthand answer assuming
import matplotlib.pyplot as plt:
plt.gca().set_title('title')
as in:
plt.subplot(221)
plt.gca().set_title('title')
plt.subplot(222)
etc...
Then there is no need for superfluous variables.
If you want to make it shorter, you could write :
import matplotlib.pyplot as plt
for i in range(4):
plt.subplot(2,2,i+1).set_title(f'Subplot n°{i+1}')
plt.show()
It makes it maybe less clear but you don't need more lines or variables
A solution I tend to use more and more is this one:
import matplotlib.pyplot as plt
fig, axs = plt.subplots(2, 2) # 1
for i, ax in enumerate(axs.ravel()): # 2
ax.set_title("Plot #{}".format(i)) # 3
Create your arbitrary number of axes
axs.ravel() converts your 2-dim object to a 1-dim vector in row-major style
assigns the title to the current axis-object
fig, (ax1, ax2, ax3, ax4) = plt.subplots(nrows=1, ncols=4,figsize=(11, 7))
grid = plt.GridSpec(2, 2, wspace=0.2, hspace=0.5)
ax1 = plt.subplot(grid[0, 0])
ax2 = plt.subplot(grid[0, 1:])
ax3 = plt.subplot(grid[1, :1])
ax4 = plt.subplot(grid[1, 1:])
ax1.title.set_text('First Plot')
ax2.title.set_text('Second Plot')
ax3.title.set_text('Third Plot')
ax4.title.set_text('Fourth Plot')
plt.show()
In case you have multiple images and you want to loop though them and show them 1 by 1 along with titles - this is what you can do. No need to explicitly define ax1, ax2, etc.
The catch is you can define dynamic axes(ax) as in Line 1 of code
and you can set its title inside a loop.
The rows of 2D array is length (len) of axis(ax)
Each row has 2 items i.e. It is list within a list (Point No.2)
set_title can be used to set title, once the proper axes(ax) or subplot is selected.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 2, figsize=(6, 8))
for i in range(len(ax)):
for j in range(len(ax[i])):
## ax[i,j].imshow(test_images_gr[0].reshape(28,28))
ax[i,j].set_title('Title-' + str(i) + str(j))
You are able to give every graph a different title and label by Iteration only.
titles = {221: 'First Plot', 222: 'Second Plot', 223: 'Third Plot', 224: 'Fourth Plot'}
fig = plt.figure()
for x in range(221,225):
ax = fig.add_subplot(x)
ax.title.set_text(titles.get(x))
plt.subplots_adjust(left=0.1,
bottom=0.1,
right=0.9,
top=0.9,
wspace=0.4,
hspace=0.4)
plt.show()
Output:
As of matplotlib 3.4.3, the Figure.add_subplot function supports kwargs with title as:
fig.add_subplot(311, title="first")
fig.add_subplot(312, title="second")
For completeness, the requested result can also be achieve without explicit reference to the figure axes as follows:
import matplotlib.pyplot as plt
plt.subplot(221)
plt.title("Title 1")
plt.subplot(222)
plt.title("Title 2")
plt.subplot(223)
plt.title("Title 3")
plt.subplot(224)
plt.title("Title 4")
Use plt.tight_layout() after the last plot if you have issues with overlapping labels.

Categories