Description
imshow
doesn't normalize the color range in RGB images
Bug summary
When single channel float image is passed to imshow
it gets normalized to range [0,1] before display. This does not happen for RGB images.
Code for reproduction
img = np.arange(0, 0.6, .1).reshape(6,1)
plt.subplot(141)
plt.title('grayscale')
plt.imshow(img)
plt.colorbar()
img = np.arange(0, 0.6, .1).repeat(3).reshape(6,1,3)
plt.subplot(142)
plt.title('RGB')
plt.imshow(img)
plt.colorbar()
img = np.arange(0, 1.6, .2).reshape(8,1)
plt.subplot(143)
plt.title('grayscale')
plt.imshow(img)
plt.colorbar()
img = np.arange(0, 1.6, .2).repeat(3).reshape(8,1,3)
plt.subplot(144)
plt.title('RGB')
plt.imshow(img)
plt.colorbar()
Actual outcome
Please also note how the colorbars are misleading.
Expected outcome
I'd expect the RGB images to look the same as grayscale.
Real life example
This is how I encountered this issue. What is the value in all three channels at [3,18]? It is actually around 1.2!
Matplotlib version: 2.0.2
Discussion
The same issue: #5382 , on SO, and another SO.
In #5382 @tacaswell explains that and RGB image "goes through a different code path which do not get passed through the normalize/colormap framework". Colormapping of course makes no sense for color images but I believe that normalization should be consistently applied to RGB images.
I got used to matplotlib normalization of single channel float images and the need of using vmin
and vmax
to avoid this normalization and intuitively expected RGB images to be treated consistently. As I noticed subsequently the docstrigs say that "the value for each component of MxNx3 and MxNx4 float arrays should be in the range 0.0 to 1.0." But I believe that to simply overflow without raising error or warning is not correct.