Matplotlib:图像结果不一致

时间:2018-11-06 11:43:41

标签: python python-3.x matplotlib

我正在尝试使用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)的图形的方法之后,我编写了以下代码(使用来自Web的多种资源)。

导入库并加载图像文件

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_')

这是224张图像之一的外观。 Image with 7th row zero

问题是,只要我坚持这种情节,它就可以完美地工作。但是,当我尝试进行一些更改(例如添加颜色栏,每个轴之间有一些间隔等)时,图像分辨率就会更改。如果在保存图形时使用 bbox_inches ='tight',它会调整所有内容,但会更改原始分辨率,同时保持图形大小不变。

还有没有其他类似于 bbox_inches ='tight'的方法,因此它可以在固定轴分辨率的同时相应地调整图形尺寸。或者,如果matplotlib中没有这样的东西,您可以建议我采用其他任何方法来合并颜色条(轴之间的小间距,每个轴的ylabel等),同时保持图像分辨率固定。

1 个答案:

答案 0 :(得分:2)

您开始的图像高度为224像素。

在前两种情况下,您将结果分布在72个像素以上。这意味着图像的任何行都有72/224 = 32%的机会显示在最终绘图中。在第52行中,您很幸运,并有三分之一的机会。

在后两种情况下,生成的图像高度为226个像素(即,仅比原始图像稍大)。在这里,您有2/224 = 0.9%的机率,一行将占用两个像素。在行号的情况下56你碰到了不幸的机会。