imshow
的默认行为是将坐标系的原点放置在左上角。这与绘制科学数据(如两个实体
x
和
y
相对)的方式不同,其中原点即对应于坐标
(0,0)
的点位于左下角,正 x 轴向右延伸,正 y 轴向上延伸。
后者只是科学惯例,虽然已有数百年历史。可以说(尽管几乎不可能有历史证据支持),x轴传统上被左对齐,因为许多语言的书写方式都是这样,而y轴朝向顶部是因为人们直觉地认为这是一个“增加” —— 就像地形的高度一样。
另一方面,对于图像,现有的惯例源于像素数据的存储方式以及在画布上排列连续像素的方法:在第一行从左到右(按照上述逻辑),然后再次从左边开始排列下一行,以此类推,对所有其他行进行排列,从上到下进行。就像排列在页面上的文字——使用从左到右且更普遍的是从上到下编写的语言一样。
正是出于这个原因,图像中的y轴采用了它现在的方向。要使y值从下往上增加,可以调用选项
origin='lower'
,以便将输入数据解释为科学惯例。但是,你也需要将图像的行
翻转倒过来,以便在屏幕上显示时图像呈现其预期的方向。这是因为当图像加载到内存中时曾经是第一行的东西现在对应于最后一个y坐标,即顶部的那个坐标。
总之,只需按以下代码中的方式调用
imshow
:
plt.imshow(np.flipud(img), cmap='gray', origin='lower')
为了进一步说明,这里提供一个自包含的示例来展示这种行为:
from imageio import imread
image = imread('https://upload.wikimedia.org/wikipedia/commons'
'/thumb/6/6a/Mona_Lisa.jpg/158px-Mona_Lisa.jpg')
from matplotlib import pyplot
figure = pyplot.figure(tight_layout=True)
(axes1, axes2, axes3) = figure.subplots(nrows=1, ncols=3)
axes1.set_title("origin='upper'")
axes1.imshow(image)
axes2.set_title("origin='lower'")
axes2.imshow(image, origin='lower')
axes3.set_title("'lower' + flipped")
axes3.imshow(image[::-1], origin='lower')
pyplot.show()
示例需要安装ImageIO才能获取示例图像。 它的输出是:
(在示例代码中,我使用了image[::-1]
来翻转图像,而不是前面提到的等效语法np.flipud(image)
。所有这样做的是避免显式地导入NumPy(作为np
),即额外的一行代码。 隐式地,NumPy仍然在工作。)
类似问题: