【发布时间】:2019-04-09 19:21:11
【问题描述】:
我正在尝试使用 matplotlib 在图中绘制多个图像。
基本上,我使用 PIl 库读取图像,将其转换为 numpy 数组并对其进行一些操作(将一行中的元素设置为零)。到目前为止一切正常。但是当我尝试使用 matplotlib 保存结果时,我得到的结果不一致。
请看一下我的代码。
导入库
import numpy as np
import matplotlib.pyplot as plt
import PIL.Image as PI
加载文件
fileName = 'n01978287_43.jpg'
img = PI.open(fileName)
size = 224
img = img.resize((size, size))
img = np.asarray(img, dtype=np.uint8).astype(np.float32)
img = img/255
结果 1
temp_img = np.copy(img)
temp_img[51, :, :] = 0*temp_img[51, :, :]
fig = plt.figure()
ax1 = plt.subplot(1, 6, 1)
ax1.imshow(img, interpolation='none')
ax2 = plt.subplot(1, 6, 2)
ax2.imshow(temp_img, interpolation='none')
plt.savefig('test_516.png')
plt.close(fig)
结果 2
temp_img = np.copy(img)
temp_img[52, :, :] = 0*temp_img[52, :, :]
fig = plt.figure()
ax1 = plt.subplot(1, 6, 1)
ax1.imshow(img, interpolation='none')
ax2 = plt.subplot(1, 6, 2)
ax2.imshow(temp_img, interpolation='none')
plt.savefig('test_526.png')
plt.close(fig)
结果 3
temp_img = np.copy(img)
temp_img[51, :, :] = 0*temp_img[51, :, :]
fig = plt.figure()
ax1 = plt.subplot(1, 2, 1)
ax1.imshow(img, interpolation='none')
ax2 = plt.subplot(1, 2, 2)
ax2.imshow(temp_img, interpolation='none')
plt.savefig('test_512.png')
plt.close(fig)
结果 4
temp_img = np.copy(img)
temp_img[56, :, :] = 0*temp_img[56, :, :]
fig = plt.figure()
ax1 = plt.subplot(1, 2, 1)
ax1.imshow(img, interpolation='none')
ax2 = plt.subplot(1, 2, 2)
ax2.imshow(temp_img, interpolation='none')
plt.savefig('test_562.png')
plt.close(fig)
现在,如果您查看结果,您会注意到不一致之处。
- 首先,对于前两张图像(6 轴图形),您仅在其中一张图像中看到黑线。 (如果您将所有行清零(一次一个)然后尝试保存结果,则有一种模式。
- 在最后两张图像中,黑线变粗。 (在这种情况下我没有找到任何模式)。
系统设置 - Python3、Matplotlib3、PIL、Numpy
更新:
在寻找以所需分辨率(在本例中为 224*224)保存图形的方法后,我编写了以下代码(使用来自网络的多个资源)。
导入库并加载图片文件
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw, ImageFont
fileName = 'n01978287_43.jpg'
img = Image.open(fileName)
size = 224
img = img.resize((size, size))
img = np.asarray(img, dtype=np.uint8).astype(np.float32)
img = img/255
绘制图像网格的功能
def plt_save(grid, idx, name):
nRows = len(grid)
nCols = len(grid[0])
print('Clearing figure')
plt.rcParams.update({'font.size': 8})
wFig = (nCols+2) # Figure width (two more than nCols because I want to add ylabels on the very left and very right of figure)
hFig = (nRows+1) # Figure height (one more than nRows becasue I want to add xlabels to the top of figure)
fig = plt.figure(figsize=( wFig, hFig ))
fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0)
fig.patch.set_facecolor('grey')
for r in range(nRows):
for c in range(nCols):
ax = plt.subplot2grid( shape=[hFig, wFig], loc=[r+1, c+1] )
im= ax.imshow(grid[r][c], interpolation='none')
ax.spines['bottom'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.set_xticks([])
ax.set_yticks([])
#fig.colorbar(im, ax=ax)
#ax.set_aspect('auto')
if not r:
ax.set_title('Image',
rotation=22.5,
horizontalalignment='left',
verticalalignment='bottom')
if not c:
ax.set_ylabel('leftLabel',
rotation=0,
horizontalalignment='right',
verticalalignment='center')
if c == wFig-3:
ax2 = ax.twinx()
#ax2.axis('off')
ax2.set_xticks([])
ax2.set_yticks([])
ax2.spines['top'].set_visible(False)
ax2.spines['right'].set_visible(False)
ax2.spines['bottom'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax2.set_ylabel( 'rightLabel',
rotation=0,
verticalalignment='center',
horizontalalignment='left' )
print('Saving file')
plt.savefig( ( str(idx) + '_' + name + '_' + fileName.split('.')[0] + '.png'),
orientation='landscape',
#bbox_inches='tight',
facecolor = fig.get_facecolor(),
dpi=224, # DPI is 224 becasue the axis size is 1x1 inch and I want 224x224 pixels in each axis
transparent=True,
frameon=False )
plt.close(fig)
循环将图像的行清零(一次一个)
for i in range(0, 224):
temp_img = np.copy(img)
temp_img[i, :, :] = 0*temp_img[i, :, :]
# 1*4 Grid of images (can vary based on the requirement)
grid = [img, temp_img, img, temp_img]
grid = [grid, grid] #2*4 grid of images
plt_save(grid, i, 'PLT_')
问题是,只要我坚持这种情节,它就可以完美运行。但是当我尝试进行一些更改时(例如添加颜色条,每个轴之间有一些空间等),图像分辨率会发生变化。如果我在保存图形时使用 bbox_inches = 'tight',它会调整所有内容,但会更改原始分辨率,同时保持图形大小不变。
有没有其他类似于bbox_inches='tight'的方式,可以在相应调整图形大小的同时保持轴分辨率固定。或者如果matplotlib中没有这样的东西,你能建议我用其他方法来合并颜色条(轴之间的小空间,每个轴的ylabel等),同时保持图像分辨率固定。
【问题讨论】:
标签: python python-3.x matplotlib