1

I want to place 3 plots using subplots. Two plots on the top row and one plot that will occupy the entire second row.

My code creates a gap between the top two plots and the lower plot. How can I correct that?

df_CI
Country China   India
1980    5123    8880
1981    6682    8670
1982    3308    8147
1983    1863    7338
1984    1527    5704

fig = plt.figure() # create figure

ax0 = fig.add_subplot(221) # add subplot 1 (2 row, 2 columns, first plot)
ax1 = fig.add_subplot(222) # add subplot 2 (2 row, 2 columns, second plot). 
ax2 = fig.add_subplot(313) # a 3 digit number where the hundreds represent nrows, the tens represent ncols 
                            # and the units represent plot_number.

# Subplot 1: Box plot
df_CI.plot(kind='box', color='blue', vert=False, figsize=(20, 20), ax=ax0) # add to subplot 1
ax0.set_title('Box Plots of Immigrants from China and India (1980 - 2013)')
ax0.set_xlabel('Number of Immigrants')
ax0.set_ylabel('Countries')

# Subplot 2: Line plot
df_CI.plot(kind='line', figsize=(20, 20), ax=ax1) # add to subplot 2
ax1.set_title ('Line Plots of Immigrants from China and India (1980 - 2013)')
ax1.set_ylabel('Number of Immigrants')
ax1.set_xlabel('Years')

# Subplot 3: Box plot
df_CI.plot(kind='bar', figsize=(20, 20), ax=ax2) # add to subplot 1
ax0.set_title('Box Plots of Immigrants from China and India (1980 - 2013)')
ax0.set_xlabel('Number of Immigrants')
ax0.set_ylabel('Countries')

plt.show()

enter image description here

1 Answer 1

6

I've always found subplots syntax a little difficult. With these calls

ax0 = fig.add_subplot(221)
ax1 = fig.add_subplot(222)

you're dividing your figure in a 2x2 grid and filling the first row.

ax2 = fig.add_subplot(313)

Now you're dividing it in three rows and filling the last one.

You're basically creating two independent subplot grids, there is no easy way to define how to space subplots from one with respect to the other.

A much easier and pythonic way is using gridspec to create a single finer grid and address it with python slicing.

fig = plt.figure()
gs = mpl.gridspec.GridSpec(2, 2, wspace=0.25, hspace=0.25) # 2x2 grid
ax0 = fig.add_subplot(gs[0, 0]) # first row, first col
ax1 = fig.add_subplot(gs[0, 1]) # first row, second col
ax2 = fig.add_subplot(gs[1, :]) # full second row

enter image description here

And now you can also easily tune spacing with wspace and hspace.

More complex layouts are also a lot easier, it's just the familiar slicing syntax.

fig = plt.figure()
gs = mpl.gridspec.GridSpec(10, 10, wspace=0.25, hspace=0.25)    
fig.add_subplot(gs[2:8, 2:8])
fig.add_subplot(gs[0, :])
for i in range(5):
    fig.add_subplot(gs[1, (i*2):(i*2+2)])
fig.add_subplot(gs[2:, :2])
fig.add_subplot(gs[8:, 2:4])
fig.add_subplot(gs[8:, 4:9])
fig.add_subplot(gs[2:8, 8])
fig.add_subplot(gs[2:, 9])
fig.add_subplot(gs[3:6, 3:6])

# fancy colors
cmap = mpl.cm.get_cmap("viridis")
naxes = len(fig.axes)
for i, ax in enumerate(fig.axes):
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_facecolor(cmap(float(i)/(naxes-1)))

gridpec complex layout

Sign up to request clarification or add additional context in comments.

1 Comment

Great Answer! Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.