Remove the extra plot in the matplotlib subplot

Question:

I want to plot 5 data frames in a 2 by 3 setting (i.e. 2 rows and 3 columns). This is my code: However there is an extra empty plot in the 6th position (second row and third column) which I want to get rid of it. I am wondering how I could remove it so that I have three plots in the first row and two plots in the second row.

import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2, ncols=3)

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



df[2].plot(kind='bar',ax=axes[0,0]); axes[0,0].set_title('2')

df[4].plot(kind='bar',ax=axes[0,1]); axes[0,1].set_title('4')

df[6].plot(kind='bar',ax=axes[0,2]); axes[0,2].set_title('6')

df[8].plot(kind='bar',ax=axes[1,0]); axes[1,0].set_title('8')

df[10].plot(kind='bar',ax=axes[1,1]); axes[1,1].set_title('10')

plt.setp(axes, xticks=np.arange(len(observations)), xticklabels=map(str,observations),
        yticks=[0,1])

fig.tight_layout()

Plots

Asked By: HimanAB

||

Answers:

Try this:

fig.delaxes(axes[1][2])

A much more flexible way to create subplots is the fig.add_axes() method. The parameters is a list of rect coordinates: fig.add_axes([x, y, xsize, ysize]). The values are relative to the canvas size, so an xsize of 0.5 means the subplot has half the width of the window.

Answered By: Johannes

Alternatively, using axes method set_axis_off():

axes[1,2].set_axis_off()
Answered By: ksha

If you know which plot to remove, you can give the index and remove like this:

axes.flat[-1].set_visible(False) # to remove last plot
Answered By: Jaswanth Kumar

Turn off all axes, and turn them on one-by-one only when you’re plotting on them. Then you don’t need to know the index ahead of time, e.g.:

import matplotlib.pyplot as plt

columns = ["a", "b", "c", "d"]
fig, axes = plt.subplots(nrows=len(columns))

for ax in axes:
    ax.set_axis_off()

for c, ax in zip(columns, axes):
    if c == "d":
        print("I didn't actually need 'd'")
        continue

    ax.set_axis_on()
    ax.set_title(c)

plt.tight_layout()
plt.show()

enter image description here

Answered By: komodovaran_

Previous solutions do not work with sharex=True. If you have that, please consider the solution below, it also deals with 2 dimensional subplot layout.

import matplotlib.pyplot as plt


columns = ["a", "b", "c", "d"]
fig, axes = plt.subplots(4,1, sharex=True)


plotted = {}
for c, ax in zip(columns, axes.ravel()):
    plotted[ax] = 0
    if c == "d":
        print("I didn't actually need 'd'")
        continue
    ax.plot([1,2,3,4,5,6,5,4,6,7])
    ax.set_title(c)
    plotted[ax] = 1

if axes.ndim == 2:
    for a, axs in enumerate(reversed(axes)):
        for b, ax in enumerate(reversed(axs)):
            if plotted[ax] == 0:
                # one can use get_lines(), get_images(), findobj() for the propose
                ax.set_axis_off()
                # now find the plot above
                axes[-2-a][-1-b].xaxis.set_tick_params(which='both', labelbottom=True)
            else:
                break # usually only the last few plots are empty, but delete this line if not the case
else:
    for i, ax in enumerate(reversed(axes)):
        if plotted[ax] == 0:
            ax.set_axis_off()
            axes[-2-i].xaxis.set_tick_params(which='both', labelbottom=True)
            # should also work with horizontal subplots
            # all modifications to the tick params should happen after this
        else:
            break

plt.show()

example run result

2 dimensional fig, axes = plot.subplots(2,2, sharex=True)

when using 2,2

Answered By: snail123815

A lazier version of Johannes’s answers is to remove any axes that haven’t had data added to them. This avoids maintaining a specification of which axes to remove.

[fig.delaxes(ax) for ax in axes.flatten() if not ax.has_data()]
Answered By: mangoUnchained
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.