我需要将图像合二为一。我希望生成的图像包含 7 行和 9 列。每个分量图像的尺寸为 256 x 256。我希望不调整这些图像的大小,也就是说,我希望生成的图像的尺寸至少为 9 * 256 x 7 * 256 = 2304 x 1792。最简单的方法对我来说,这样做将使用 numpy 并使用例如 np.concatenate 将图像连接在一起。但是,我决定使用 matplotlib,因为用它向轴添加标签要容易得多。
不幸的是,我无法设置正确的 figsize 和 dpi 值。
我发现一个好方法是将 dpi 参数设置为 100,例如将高度设置为以像素为单位的高度除以 dpi 值。如下所示。
cols = 9
rows = 7
img_size = (256, 256)
dpi = 100
fig, axes = plt.subplots(rows, cols, figsize=(img_size[0] * cols // dpi, img_size[1] * rows // dpi), dpi=dpi)
不幸的是,当我保存这张图片时,它的尺寸是 2359 x 1720.
我的第二个问题是,尽管设置了 wspace=0 和 hspace=0,但子图之间仍然存在间隙。
plt.subplots_adjust(wspace=0, hspace=0, left=0, bottom=0, right=1, top=1)
下面我附上一个简单的例子进行复现
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
cols = 9
rows = 7
img_size = (256, 256)
dpi = 100
fig, axes = plt.subplots(rows, cols, figsize=(img_size[0] * cols // dpi, img_size[1] * rows // dpi), dpi=dpi)
for row_idx, row in enumerate(axes):
images = [Image.new('RGB', (256, 256), color='grey') for i in range(cols)]
for col_idx, (col, image) in enumerate(zip(row, images)):
col.imshow(image)
col.spines['top'].set_visible(False)
col.spines['right'].set_visible(False)
col.spines['bottom'].set_visible(False)
col.spines['left'].set_visible(False)
col.set_xticks([])
col.set_yticks([])
if col_idx == 0:
col.set_ylabel('name', fontsize=30)
plt.subplots_adjust(wspace=0, hspace=0, left=0, bottom=0, right=1, top=1)
plt.savefig('example.png', bbox_inches='tight', format='png')
plt.show()
我不明白为什么你需要特定的尺寸。根据最终文档中图像的缩放比例,尺寸将变得无关紧要。
不幸的是,我没有针对这些差距的直接解决方案,但由于我想知道为什么不在 numpy 中组合图像然后使用 matplotlib 进行标记,我根据您的代码进行了一些尝试(顺便说一下,感谢非常好的示例代码!):
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
cols = 9
rows = 7
img_size = (256, 256)
dpi = 500
fig = plt.figure(figsize=(13, 9), dpi=dpi)
# generating a single image
idx = 0
image = np.array([])
for row_idx in range(rows):
colors = ['grey', 'blue'] # used to crate a chessboard pattern, which was better for visual feedback
images = [Image.new('RGB', (256, 256), color=colors[(row_idx + i) % 2]) for i in range(cols)]
row_image = np.concatenate(images, axis=1)
if row_idx == 0:
image = row_image
else:
image = np.concatenate((image, row_image))
plt.imshow(image, origin="lower")
axes = plt.gca()
axes.spines['top'].set_visible(False)
axes.spines['bottom'].set_visible(False)
axes.spines['left'].set_visible(False)
axes.set_xticks([])
axes.set_yticks([128 + idx * 256 for idx in range(rows)])
axes.set_yticklabels(["Name" for _ in range(rows)], rotation=90, fontsize=30, va="center") # va="center" centers the label nicely
plt.subplots_adjust(wspace=0, hspace=0, left=0, bottom=0, right=1, top=1)
plt.savefig('example1.pdf', bbox_inches='tight', format='pdf')
plt.savefig('example1.png', bbox_inches='tight', format='png')
plt.show()