关闭子图中的坐标轴

110
我有以下代码:
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()

然而,由于坐标轴上的数值,结果看起来相当丑陋。

2x2 subplots

如何同时关闭所有子图的坐标轴值?
因为我不知道如何使其与子图一起工作,所以如何删除坐标轴、图例和白色填充无法解决我的问题。

https://dev59.com/Xmox5IYBdhLWcg3wTina 这个链接有什么问题吗?另外,你能让你的代码可运行吗? - Veedrac
1
轴偏移问题只会导致最后一个子图不可见。 - Sergey Ivanov
3个回答

189
你可以按照Veedrac的评论中的建议(链接到这里)关闭Axes,只需做一个小修改。
不要使用plt.axis('off'),而是使用ax.axis('off'),其中ax是一个matplotlib.axes对象。
  • 要做到这一点,对每个子图索引每个Axes,例如axs[0, 0].axis('off'),以此类推。
  • 请参阅原生Matplotlib接口,了解pyplotAxes之间的区别。
下面的代码显示了没有prune_matrix的结果,因为它不可用。
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.cm as cm
import matplotlib.cbook as cbook  # used for matplotlib sample image

# load readily available sample image
with cbook.get_sample_data('grace_hopper.jpg') as image_file:
    img = plt.imread(image_file)

# read a local file
# img = mpimg.imread("file.jpg")

fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(8, 8), tight_layout=True)
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()

enter image description here

注意:要仅关闭 x 轴或 y 轴,您可以使用 set_visible() 方法,例如:
axs[0, 0].xaxis.set_visible(False) # Hide only x axis

迭代方法
fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(8, 8), tight_layout=True)

# convert the 2d array to 1d, which removes the need to iterate through i and j
axs = axs.flat
ranks = [512, 128, 32, 16]

# iterate through each Axes with the associate rank
for ax, rank in zip(axs, ranks):

    ax.imshow(img, cmap=cm.Greys_r)
    ax.set_title(f'Rank = {rank}')
    ax.axis('off')

plt.show()

36

给定:

import matplotlib.pyplot as plt

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

关闭所有子图的坐标轴:
for ax in axs.ravel():
    ax.set_axis_off()

5
如果您正在使用Python 3,map函数是惰性求值的,因此您需要将其包装在list函数中。 - Milo Wielondek
我必须执行[axi.axis_off() for axi in ax.ravel()] - Alex Witsil
1
我曾经使用map()在Py2中,然后在Py3中使用列表推导式来编写循环。这不好。它似乎可以节省一行代码,但这并不是一个很好的节省方式,如果循环很长,那么你会浪费内存和资源(除非你真的使用了列表)。只需编写for axi in ax.ravel(): axi.set_axis_off() # noqa(1行,noqa用于flake8,这是一个很好的工具)。或者承认这是一个循环,并在冒号后按Enter键。 - Tomasz Gandor

1
另一种可能的方式是在每个绘图的轴上将axison属性设为False。
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

如果你想清楚地看到被移除的内容,你可以使用Axes.set()分别"移除"框架和刻度。
        axs[i,j].set(frame_on=False, xticks=[], yticks=[])

最后,如果你想在绘制完图形后去除边框和刻度线,你可以遍历图形本身中的轴列表。
for ax in fig.axes:
    ax.axison = False

注意:这里提供的三种方法(axis('off')set_axis_off()axison=False)是等效的方法,因为在底层,axis('off')调用了set_axis_off(),而set_axis_off()又将axison=False,所以最终它们是相同的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接