首页 > 解决方案 > Matplotlib:子图的居中

问题描述

这是我的代码

import matplotlib.pyplot as plt
import numpy as np

steps = 20
fig = plt.figure()
for k in range(steps):
    ax = fig.add_subplot(1,steps,(k+1))
    ax.imshow(np.random.rand(30,30), interpolation="none", cmap="gray")
    ax.axis("off")
fig.tight_layout()
plt.subplots_adjust(right=0.97,\
                    left=0.03,\
                    bottom=0.03,\
                    top=0.97,\
                    wspace=0.1,\
                    hspace=0.1)
plt.savefig("test.png", dpi=300, bbox_inches="tight")
plt.close(fig)

产生以下输出:

在此处输入图像描述

但我真的很想拥有这样的东西: 在此处输入图像描述

只有突出显示的部分。居中,子图周围没有太多空白。

我有两个问题,我在互联网上找到的关于子图的其他类似帖子无法解决。我怎样才能使我的情节水平和垂直居中?是什么导致地块不居中?这可能是plt.subplots_adjust()我也不太明白的原因。调整值有时会导致不直观的结果(在我看来)。如何subplots_adjust自动调整 的值,以便对于任意数量的子图,所有内容都居中,周围没有太多空白?

标签: pythonmatplotlib

解决方案


bbox_inches="tight"自动尝试“猜测”从图中裁剪多少。如果您想完全控制定位,这可能会导致不希望的结果。

现在的主要目标是首先获得所需尺寸的图形。

粗略估计,图形高度需要为 1/步加上一些边距。例如

steps = 20
fig = plt.figure(figsize=(12,(12+3)/steps))

给出了一个很好的结果

import matplotlib.pyplot as plt
import numpy as np

steps = 20
fig = plt.figure(figsize=(12,(12+3)/steps))
for k in range(steps):
    ax = fig.add_subplot(1,steps,(k+1))
    ax.imshow(np.random.rand(30,30), interpolation="none", cmap="gray")
    ax.axis("off")

plt.subplots_adjust(right=0.97,\
                    left=0.03,\
                    bottom=0.03,\
                    top=0.97,\
                    wspace=0.1,\
                    hspace=0.1)
plt.savefig("test.png", dpi=300, facecolor="palegreen")
plt.show()
plt.close(fig)

在此处输入图像描述

您当然可以调整图形大小和子图参数以精确匹配。例如,您从给定的图形宽度开始计算图形高度,同时考虑所有子图参数和图像的方面(在此处更改以使其效果更清晰)。

import matplotlib.pyplot as plt
import numpy as np

steps = 20

# subplot parameters
sp = dict(right=0.98,\
          left=0.02,\
          bottom=0.1,\
          top=0.9,\
          wspace=0.1,\
          hspace=0.1)
figw = 12 #inches
aspect = 30/50 # aspect of the images (heigth/width)
axs = (figw*(sp["right"]-sp["left"]))/(steps+(steps-1)*sp["wspace"])
figh = axs*aspect/(sp["top"]-sp["bottom"])

fig = plt.figure(figsize=(figw, figh))

for k in range(steps):
    ax = fig.add_subplot(1,steps,(k+1))
    ax.imshow(np.random.rand(30,50), interpolation="none", cmap="gray")
    ax.axis("off")

plt.subplots_adjust(**sp)
plt.savefig("test.png", dpi=300, facecolor="palegreen")
plt.show()
plt.close(fig)

在此处输入图像描述


推荐阅读