python matplotlib 的 gridspec 无法减少子图之间的差距
python matplotlib's gridspec unable to reduce gap between subplots
我正在使用 GridSpec 在子图中绘制子图以显示图像。
在下面的示例代码中,我创建了一个 1x2 子图,其中每个子图轴包含 3x3 子图(第一个子图中的子图)。
3x3 子图基本上是将图像切割成 9 个方块,排列成 3x3 的形式。我不希望图像片段之间有任何间距,所以我将 wspace
和 hspace
都设置为 0。奇怪的是,生成的输出子图显示行之间的垂直间隙。
我尝试将 hspace
设置为负值以减少行之间的垂直间距,但它会导致行重叠。有没有更方便的方法来实现?
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from PIL import Image
from sklearn.datasets import load_sample_image
flower = load_sample_image('flower.jpg')
img = Image.fromarray(flower)
img = img.crop((100, 100, 325, 325))
# Create tiles - cuts image to 3x3 square tiles
n_tiles = 9
tile_size = float(img.size[0]) / 3 # assumes square tile
tiles = [None] * n_tiles
for n in range(n_tiles):
row = n // 3
col = n % 3
# compute tile coordinates in term of the image (0,0) is top left corner of the image
left = col * tile_size
upper = row * tile_size
right = left + tile_size
lower = upper + tile_size
tile_coord = (int(left), int(upper), int(right), int(lower))
tile = img.crop(tile_coord)
tiles[n] = tile
# plot subplot of subplot using gridspec
fig = plt.figure(figsize=(7, 3))
outer = gridspec.GridSpec(1, 3, wspace=1)
# image shown as 3x3 grid of image tiles
inner = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer[0], wspace=0, hspace=0)
for j in range(len(tiles_tensor)):
ax1 = plt.Subplot(fig, inner[j], xticks=[], yticks=[])
ax1.imshow(tiles[j])
fig.add_subplot(ax1)
# image shown as 3x3 grid of image tiles
inner = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer[1], wspace=0, hspace=0)
for j in range(len(data)):
ax2 = plt.Subplot(fig, inner[j], xticks=[], yticks=[])
ax2.imshow(tiles[j])
fig.add_subplot(ax2)
主要问题是 imshow
默认为 aspect='equal'
。这迫使小瓷砖成为方形。但是次要地块不是正方形的,所以 9 个正方形瓷砖拼在一起并不能很好地填满次要地块。
一个简单的解决方案是通过 imshow(..., aspect='auto')
关闭方形纵横比。为了让子图更方正,可以调整 top
、bottom
、left
和 right
设置。
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from PIL import Image
from sklearn.datasets import load_sample_image
flower = load_sample_image('flower.jpg')
img = Image.fromarray(flower)
img = img.crop((100, 100, 325, 325))
# Create tiles - cuts image to 3x3 square tiles
n_tiles = 9
tile_size = float(img.size[0]) / 3 # assumes square tile
tiles = [None] * n_tiles
for n in range(n_tiles):
row = n // 3
col = n % 3
# compute tile coordinates in term of the image (0,0) is top left corner of the image
left = col * tile_size
upper = row * tile_size
right = left + tile_size
lower = upper + tile_size
tile_coord = (int(left), int(upper), int(right), int(lower))
tile = img.crop(tile_coord)
tiles[n] = tile
# plot subplot of subplot using gridspec
fig = plt.figure(figsize=(7, 3))
outer = gridspec.GridSpec(1, 2, wspace=1, left=0.1, right=0.9, top=0.9, bottom=0.1)
titles = [f'Subplot {j+1}' for j in range(outer.nrows * outer.ncols) ]
for j in range(len(titles)):
ax = plt.Subplot(fig, outer[j], xticks=[], yticks=[])
ax.axis('off')
ax.set_title(titles[j])
fig.add_subplot(ax)
# image shown as 3x3 grid of image tiles
inner = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer[0], wspace=0, hspace=0)
for j in range(len(tiles)):
ax1 = plt.Subplot(fig, inner[j], xticks=[], yticks=[])
ax1.imshow(tiles[j], aspect='auto')
fig.add_subplot(ax1)
# image shown as 3x3 grid of image tiles
inner = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer[1], wspace=0, hspace=0)
for j in range(len(tiles)):
ax2 = plt.Subplot(fig, inner[j], xticks=[], yticks=[])
ax2.imshow(tiles[j], aspect='auto')
fig.add_subplot(ax2)
fig.suptitle('Overall title')
plt.show()
我正在使用 GridSpec 在子图中绘制子图以显示图像。
在下面的示例代码中,我创建了一个 1x2 子图,其中每个子图轴包含 3x3 子图(第一个子图中的子图)。
3x3 子图基本上是将图像切割成 9 个方块,排列成 3x3 的形式。我不希望图像片段之间有任何间距,所以我将 wspace
和 hspace
都设置为 0。奇怪的是,生成的输出子图显示行之间的垂直间隙。
我尝试将 hspace
设置为负值以减少行之间的垂直间距,但它会导致行重叠。有没有更方便的方法来实现?
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from PIL import Image
from sklearn.datasets import load_sample_image
flower = load_sample_image('flower.jpg')
img = Image.fromarray(flower)
img = img.crop((100, 100, 325, 325))
# Create tiles - cuts image to 3x3 square tiles
n_tiles = 9
tile_size = float(img.size[0]) / 3 # assumes square tile
tiles = [None] * n_tiles
for n in range(n_tiles):
row = n // 3
col = n % 3
# compute tile coordinates in term of the image (0,0) is top left corner of the image
left = col * tile_size
upper = row * tile_size
right = left + tile_size
lower = upper + tile_size
tile_coord = (int(left), int(upper), int(right), int(lower))
tile = img.crop(tile_coord)
tiles[n] = tile
# plot subplot of subplot using gridspec
fig = plt.figure(figsize=(7, 3))
outer = gridspec.GridSpec(1, 3, wspace=1)
# image shown as 3x3 grid of image tiles
inner = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer[0], wspace=0, hspace=0)
for j in range(len(tiles_tensor)):
ax1 = plt.Subplot(fig, inner[j], xticks=[], yticks=[])
ax1.imshow(tiles[j])
fig.add_subplot(ax1)
# image shown as 3x3 grid of image tiles
inner = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer[1], wspace=0, hspace=0)
for j in range(len(data)):
ax2 = plt.Subplot(fig, inner[j], xticks=[], yticks=[])
ax2.imshow(tiles[j])
fig.add_subplot(ax2)
主要问题是 imshow
默认为 aspect='equal'
。这迫使小瓷砖成为方形。但是次要地块不是正方形的,所以 9 个正方形瓷砖拼在一起并不能很好地填满次要地块。
一个简单的解决方案是通过 imshow(..., aspect='auto')
关闭方形纵横比。为了让子图更方正,可以调整 top
、bottom
、left
和 right
设置。
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from PIL import Image
from sklearn.datasets import load_sample_image
flower = load_sample_image('flower.jpg')
img = Image.fromarray(flower)
img = img.crop((100, 100, 325, 325))
# Create tiles - cuts image to 3x3 square tiles
n_tiles = 9
tile_size = float(img.size[0]) / 3 # assumes square tile
tiles = [None] * n_tiles
for n in range(n_tiles):
row = n // 3
col = n % 3
# compute tile coordinates in term of the image (0,0) is top left corner of the image
left = col * tile_size
upper = row * tile_size
right = left + tile_size
lower = upper + tile_size
tile_coord = (int(left), int(upper), int(right), int(lower))
tile = img.crop(tile_coord)
tiles[n] = tile
# plot subplot of subplot using gridspec
fig = plt.figure(figsize=(7, 3))
outer = gridspec.GridSpec(1, 2, wspace=1, left=0.1, right=0.9, top=0.9, bottom=0.1)
titles = [f'Subplot {j+1}' for j in range(outer.nrows * outer.ncols) ]
for j in range(len(titles)):
ax = plt.Subplot(fig, outer[j], xticks=[], yticks=[])
ax.axis('off')
ax.set_title(titles[j])
fig.add_subplot(ax)
# image shown as 3x3 grid of image tiles
inner = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer[0], wspace=0, hspace=0)
for j in range(len(tiles)):
ax1 = plt.Subplot(fig, inner[j], xticks=[], yticks=[])
ax1.imshow(tiles[j], aspect='auto')
fig.add_subplot(ax1)
# image shown as 3x3 grid of image tiles
inner = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=outer[1], wspace=0, hspace=0)
for j in range(len(tiles)):
ax2 = plt.Subplot(fig, inner[j], xticks=[], yticks=[])
ax2.imshow(tiles[j], aspect='auto')
fig.add_subplot(ax2)
fig.suptitle('Overall title')
plt.show()