107

I have the following code:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.cm as cm

img = mpimg.imread("lena.jpg")

fig, axs = plt.subplots(2, 2)
axs[0,0].imshow(img, cmap = cm.Greys_r)
axs[0,0].set_title("Rank = 512")

rank = 128
new_img = prune_matrix(rank, img)
axs[0,1].imshow(new_img, cmap = cm.Greys_r)
axs[0,1].set_title("Rank = %s" %rank)

rank = 32
new_img = prune_matrix(rank, img)
axs[1,0].imshow(new_img, cmap = cm.Greys_r)
axs[1,0].set_title("Rank = %s" %rank)

rank = 16
new_img = prune_matrix(rank, img)
axs[1,1].imshow(new_img, cmap = cm.Greys_r)
axs[1,1].set_title("Rank = %s" %rank)

plt.show()

However, the result is pretty ugly because of the values on the axes:

2x2 subplots

How can I turn off axes values for all subplots simultaneously?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Sergey Ivanov
  • 3,719
  • 7
  • 34
  • 59
  • What's wrong with http://stackoverflow.com/questions/9295026/matplotlib-plots-removing-axis-legends-and-white-spaces? Also, can you make your code runnable? – Veedrac Sep 16 '14 at 06:36
  • 1
    The problem that axis off makes invisible only the last subplot. – Sergey Ivanov Sep 16 '14 at 06:39

3 Answers3

182

You can turn the axes off by following the advice in Veedrac's comment (linking to here) with one small modification.

Rather than using plt.axis('off') you should use ax.axis('off') where ax is a matplotlib.axes object. To do this for your code you simple need to add axs[0,0].axis('off') and so on for each of your subplots.

The code below shows the result (I've removed the prune_matrix part because I don't have access to that function, in the future please submit fully working code.)

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.cm as cm

img = mpimg.imread("stewie.jpg")

fig, axs = plt.subplots(2, 2)
axs[0,0].imshow(img, cmap = cm.Greys_r)
axs[0,0].set_title("Rank = 512")
axs[0,0].axis('off')

axs[0,1].imshow(img, cmap = cm.Greys_r)
axs[0,1].set_title("Rank = %s" % 128)
axs[0,1].axis('off')

axs[1,0].imshow(img, cmap = cm.Greys_r)
axs[1,0].set_title("Rank = %s" % 32)
axs[1,0].axis('off')

axs[1,1].imshow(img, cmap = cm.Greys_r)
axs[1,1].set_title("Rank = %s" % 16)
axs[1,1].axis('off')

plt.show()

Stewie example

Note: To turn off only the x or y axis you can use set_visible() e.g.:

axs[0,0].xaxis.set_visible(False) # Hide only x axis
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Ffisegydd
  • 51,807
  • 15
  • 147
  • 125
36

Given:

import matplotlib.pyplot as plt

fig, axs = plt.subplots(2, 2)

To turn off axes for all subplots:

for ax in axs.ravel():
    ax.set_axis_off()
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Nirmal
  • 1,285
  • 2
  • 13
  • 23
  • 5
    If you're using python 3, `map` is lazily evaluated so you'll have to wrap it in `list` – Milo Wielondek Apr 23 '20 at 12:49
  • I had to do ```[axi.axis_off() for axi in ax.ravel()]``` – Alex Witsil Jan 12 '21 at 00:05
  • 1
    I used to do this - using `map()` in Py2, and then list comprehension in Py3 to write loops. This is not good. It seems to save 1 line, but it's not a great saving, and if the loop is long, you're wasting memory and resources that way (unless you actually use the list). Just write `for axi in ax.ravel(): axi.set_axis_off() # noqa` (1 line, noqa is for flake8, which is good to use). Or admit that it's a loop, and press Enter after the colon. – Tomasz Gandor Jul 05 '21 at 18:29
0

Another possible way is to set the axison attribute to False for each Axes as they get plotted.

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img = mpimg.imread("Stewie_Griffin.png")

fig, axs = plt.subplots(2, 2)

for i, lst in enumerate([[512, 128], [32, 16]]):
    for j, rank in enumerate(lst):
        axs[i,j].imshow(img)
        axs[i,j].set_title(f"Rank = {rank}")
        axs[i,j].axison = False           # <---- remove axis

img1

If you want to clearly see what is removed, you can "remove" frames and ticks separately using Axes.set().

        axs[i,j].set(frame_on=False, xticks=[], yticks=[])

Finally, if you want to remove the frames and ticks after the graphs are plotted, you can loop over the list of axes in the figure itself.

for ax in fig.axes:
    ax.axison = False

N.B. All three methods given here (axis('off'), set_axis_off() and axison=False) are equivalent methods because under the hood, axis('off') calls set_axis_off(), which in turns does axison=False, so ultimately, they are the same.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
cottontail
  • 10,268
  • 18
  • 50
  • 51