如何在Matplotlib中创建一个空的子图?

124

我正在使用matplotlib制作一个subplot组(比如,3x2),但是我只有少于6个数据集。如何使其余的subplot为空白?

排列看起来像这样:

+----+----+
| 0,0| 0,1|
+----+----+
| 1,0| 1,1|
+----+----+
| 2,0| 2,1|
+----+----+

这可能需要多页才能完成,但在最后一页中,例如有5个数据集,而2.1框将为空。但是,我已经将该图形声明为:

cfig,ax = plt.subplots(3,2)

对于subplot 2,1,有一个默认的轴线和刻度标签。如何通过编程让这个空间变成空白而没有轴线呢?

6个回答

217
你可以隐藏你不需要的坐标轴。例如,下面的代码完全关闭了第6个轴:
import matplotlib.pyplot as plt

hf, ha = plt.subplots(3,2)
ha[-1, -1].axis('off')

plt.show()

并产生以下图形:

一个3x2的图表网格,右下角没有呈现任何图表

或者,查看问题《如何在matplotlib中隐藏坐标轴文本》的被接受的答案,该方法可以保留坐标轴但隐藏所有坐标轴的装饰(例如刻度线和标签)。


谢谢 - 这实际上更接近我的原始问题。我已经接受了其他答案并调整了我的代码来使用它,但两种方法都很好。 - mishaF
很酷,确实不错,因为少了add_subplot()的混乱。 - moooeeeep
这太棒了! - FaCoffee
这并没有展示任何图形,可以说这是一个空白的图形。我正在寻找一个没有数据的图形,以明确地显示没有数据。有什么简单的修改方法可以实现这个目标吗? - Zelphir Kaltstahl
@Zelphir 我不确定你想要什么:其他五个图表都是没有数据的空图表,所以我不确定你需要什么额外的内容。此外,这是一个新问题。将来请提出一个新问题,而不是在旧答案上进行评论。 - Chris
显示剩余2条评论

29

自从第一次提出这个问题以来,Matplotlib已经添加了一个极大改进的子图界面。现在,您可以创建恰好需要的子图,而不会隐藏额外的内容。此外,子图还可以跨越更多的行或列。

import pylab as plt

ax1 = plt.subplot2grid((3,2),(0, 0))
ax2 = plt.subplot2grid((3,2),(0, 1))
ax3 = plt.subplot2grid((3,2),(1, 0))
ax4 = plt.subplot2grid((3,2),(1, 1))
ax5 = plt.subplot2grid((3,2),(2, 0))

plt.show()

输入图像描述


哇 - 这是一个不错的改进。简单多了!感谢 @Hooked! - mishaF
@Hooked,最后一个空白处非常适合添加图例。你知道在那里设置图例的方式吗? - Stefano
@Stefano 当然有做这件事的方法 - 但最好将其作为一个新问题提出,你甚至可以在问题中链接这个答案(欢迎来到StackOverflow!) - Hooked

16

使用Axes.set_visible()方法也可以隐藏子图。

import matplotlib.pyplot as plt
import pandas as pd

fig = plt.figure()
data = pd.read_csv('sampledata.csv')

for i in range(0,6):
    ax = fig.add_subplot(3,2,i+1)
    ax.plot(range(1,6), data[i])
    if i == 5:
        ax.set_visible(False)

您的答案对于原始Axes和扩展GeoAxes都非常棒! - Fei Yao

2

在需要时创建子图是否是一个选项?

import matplotlib
matplotlib.use("pdf")
import matplotlib.pyplot as plt

plt.figure()
plt.gcf().add_subplot(421)
plt.fill([0,0,1,1],[0,1,1,0])
plt.gcf().add_subplot(422)
plt.fill([0,0,1,1],[0,1,1,0])
plt.gcf().add_subplot(423)
plt.fill([0,0,1,1],[0,1,1,0])
plt.suptitle("Figure Title")
plt.gcf().subplots_adjust(hspace=0.5,wspace=0.5)
plt.savefig("outfig")

我不这么认为,因为我还有其他需要做的格式调整,但出于简洁起见,我没有在原始问题中包含它们。其中之一是plt.subplots_adjust(wspace=0,hspace=0)。我不确定事后使用它是否有效。 - mishaF
@mishaF:你可以使用这种方法来进行subplots_adjust()。请参考我的编辑。 - moooeeeep

2

在较新的matplotlib版本(自3.4.0起),您可以使用字符串数组来设计子图模式(行和列),并通过调用matplotlib.pyplot.subplot_mosaic来创建图形。

不再使用cfig, ax = plt.subplots(3,2),而是使用cfig, axs = plt.subplot_mosaic(mosaic),并以以下方式定义mosaic

mosaic = [['a', 'b'],
          ['c', 'd'],
          ['e', '.']]

在这个模式中,空白的子图用'.'表示(默认情况下,可以在调用中进行参数化)。您不需要删除空白的子图,因为它们甚至都没有被创建。
要选择一个轴进行绘图,只需使用axs[id],其中id是用于标识马赛克数组中的子图的字符串。
示例:
mosaic = [['b', 'a'], ['.', 'au']]
kw = dict(layout='constrained')
fig, axs = plt.subplot_mosaic(mosaic, **kw)

ax = axs['b']
ax.grid(axis='y')
ax.bar(n, d)

ax = axs['a']
ax.grid(axis='y')
ax.bar(n, prior)

[...]

enter image description here

使用subplot_mosaic,不仅可以引入空的子图,还可以合并“单元格”以创建多行和/或多列的子图,只需构建所需的镶嵌数组,其余代码保持不变。此外,mosaic不需要是一个数组,它也可以是一个多行字符串。例如,从复杂和语义化的图形组合中使用:
"""
A.C
BBB
.D.
"""

结果如下:

enter image description here


1
功能更强大了!感谢更新,@mins。 - mishaF

1
要删除位于 (2,1) 的图形,您可以使用
import matplotlib.pyplot as plt
cfig,ax = plt.subplots(3,2)
cfig.delaxes(ax.flatten()[5])


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