简体   繁体   中英

Why “matplotlib.pyplot.imshow” returns shapes with a frame around them?

My question is simple: why do the two pieces of code that I wrote below give two slightly different outputs?

More specifically the first one makes use of a numpy.ndarray of shape (1000, 1000) filled with "1.0" np.float64 values, except for the region where I want to have a "square", which is filled with "0.45" np.float64 values. When I call the plt.imshow method on the Axes, using as colormap "nipy_spectral", it returns a square, but with a weird frame around it...

See the code below and the left picture at the end:

#Code1:
foreground = np.ones((1000, 1000))
foreground = foreground.astype(np.float64)

def drawSquare(centerYX : tuple = (0, 0), radius : int = 1):
    squareCoordinates = np.meshgrid([y for y in range(centerYX[0]-radius, centerYX[0]+radius+1, 1)],
                                    [x for x in range(centerYX[1]-radius, centerYX[1]+radius+1, 1)])
    return squareCoordinates

square1 = drawSquare((round(foreground.shape[0]/2), round(foreground.shape[1]/2)), 200)
foreground[square1[0], square1[1]] = 0.45

fig, ax = plt.subplots(1)
ax.imshow(foreground, cmap = "nipy_spectral", vmin = 0.0, vmax = 1.0, , interpolation = None)
plt.show();

In the second piece of code, I make use of a numpy.ndarray of shape (1000, 1000, 4) which I fill with the RGBA sequence corresponding to the last color of the "nipy_spectral" colormap (my background), except for the square region, that I fill with the RGBA sequence obtained by calling the "nipy_spectral" colormap with the argument "0.45".

In this case, I already have an RGBA image/array that does not need any conversion via the "cmap" argument of the Axes.imshow method. In this case, the output is the expected one: a square without any weird frame around it .

See the code below and the right picture at the end:

#Code2:
foreground = np.zeros((1000, 1000, 4))
foreground[:, :] = [0.8, 0.8, 0.8, 1.0]
foreground = foreground.astype(np.float64)

def drawSquare(centerYX : tuple = (0, 0), radius : int = 1):
    squareCoordinates = np.meshgrid([y for y in range(centerYX[0]-radius, centerYX[0]+radius+1, 1)],
                                    [x for x in range(centerYX[1]-radius, centerYX[1]+radius+1, 1)])
    return squareCoordinates

square1 = drawSquare((round(foreground.shape[0]/2), round(foreground.shape[1]/2)), 200)

nipy_spectral_cm = matplotlib.cm.get_cmap("nipy_spectral")
foreground[square1[0], square1[1]] = nipy_spectral_cm(0.45)

fig, ax = plt.subplots(1)
ax.imshow(foreground)
plt.show();

在此处输入图像描述

Why does the first piece of code (Code1) give a square with that weird frame around it?

The frame is due to interpolation. It's present in the second code too (just zoom in the image and you'll see it), but less visible because its color is closer to the color of the green square:

Code 2 --> interpolates to a bluish green:

foreground[299:301,299:301,0]
#array([[0.8, 0.8],
#       [0.8, 0. ]])

foreground[299:301,299:301,1]
#array([[0.8       , 0.8       ],
#       [0.8       , 0.60261373]])

foreground[299:301,299:301,2]
#array([[0.8, 0.8],
#       [0.8, 0. ]])

Code 1 --> interpolates to yellow:

foreground[299:301,299:301]
#array([[1.  , 1.  ],
#       [1.  , 0.45]])

Use interpolate='none' to switch off interpolation and get a clear cut corner. You used None instead of 'none' . None is the default and is preset to 'antialiased' , see here for details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM