Matplotlib imshow() 函数
imshow() 用于在 Axes 上显示图像或渲染二维数组为热力图。
它是最常用的二维数据可视化函数,支持多种插值、颜色映射和缩放方式。
函数定义
pyplot 接口
matplotlib.pyplot.imshow(X, cmap=None, norm=None, *, aspect=None,
interpolation=None, alpha=None, vmin=None, vmax=None, origin=None,
extent=None, filternorm=True, filterrad=4.0, resample=None,
url=None, **kwargs)
Axes 接口
Axes.imshow(X, cmap=None, norm=None, *, aspect=None,
interpolation=None, alpha=None, vmin=None, vmax=None, origin=None,
extent=None, filternorm=True, filterrad=4.0, resample=None,
url=None, **kwargs)
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| X | array-like 或 PIL Image | 要显示的图像数据。2D 数组显示为灰度/伪彩色,3D 数组(MxNx3 或 MxNx4)显示为 RGB/RGBA 图像 |
| cmap | str 或 Colormap | 颜色映射,仅对 2D 数据有效。默认 'viridis' |
| norm | Normalize 或 str | 数据归一化方式,如 'linear'、'log'、'symlog' |
| aspect | str 或 float | 像素宽高比:'equal'(默认,像素为正方形)、'auto'(自动填充Axes)、数字(自定义比例) |
| interpolation | str | 插值方法:'none'/'nearest'(无插值)、'bilinear'、'bicubic'、'antialiased'(默认) 等 |
| alpha | float 或 array-like | 透明度,0-1 |
| vmin, vmax | float | 颜色映射的数据范围 |
| origin | str | 原点位置:'upper'(默认,[0,0]在左上角) 或 'lower'([0,0]在左下角) |
| extent | tuple (left,right,bottom,top) | 数据边界坐标,改变轴标签但不改变数据 |
origin='upper'(默认)将数组第一行放在顶部,符合图像显示习惯。origin='lower'将第一行放在底部,符合数学坐标系习惯。
使用示例
示例 1:显示二维数组(热力图)
实例
import matplotlib.pyplot as plt
import numpy as np
# 创建 10x10 的二维数组
np.random.seed(42)
data = np.random.rand(10, 10)
fig, ax = plt.subplots(figsize=(6, 5), layout='constrained')
# 显示为热力图
im = ax.imshow(data, cmap='viridis', aspect='auto')
# 在每个单元格显示数值
for i in range(10):
for j in range(10):
color = 'white' if data[i, j] > 0.5 else 'black'
ax.text(j, i, f'{data[i,j]:.2f}', ha='center',
va='center', color=color, fontsize=8)
# 添加颜色条
fig.colorbar(im, ax=ax, label='Value', shrink=0.8)
ax.set_title('2D Array as Heatmap')
ax.set_xlabel('Column')
ax.set_ylabel('Row')
plt.show()
import numpy as np
# 创建 10x10 的二维数组
np.random.seed(42)
data = np.random.rand(10, 10)
fig, ax = plt.subplots(figsize=(6, 5), layout='constrained')
# 显示为热力图
im = ax.imshow(data, cmap='viridis', aspect='auto')
# 在每个单元格显示数值
for i in range(10):
for j in range(10):
color = 'white' if data[i, j] > 0.5 else 'black'
ax.text(j, i, f'{data[i,j]:.2f}', ha='center',
va='center', color=color, fontsize=8)
# 添加颜色条
fig.colorbar(im, ax=ax, label='Value', shrink=0.8)
ax.set_title('2D Array as Heatmap')
ax.set_xlabel('Column')
ax.set_ylabel('Row')
plt.show()
示例 2:extent 参数控制坐标轴
实例
import matplotlib.pyplot as plt
import numpy as np
# 创建 50x50 的数学函数数据
x = np.linspace(-3, 3, 50)
y = np.linspace(-3, 3, 50)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5),
layout='constrained')
# 左图:不使用 extent,轴坐标为像素索引
im1 = ax1.imshow(Z, cmap='RdYlBu', origin='lower')
ax1.set_title('Without extentn(pixel indices)')
fig.colorbar(im1, ax=ax1, shrink=0.8)
# 右图:使用 extent,轴坐标为实际数据坐标
im2 = ax2.imshow(Z, cmap='RdYlBu', origin='lower',
extent=[-3, 3, -3, 3]) # [xmin, xmax, ymin, ymax]
ax2.set_title('With extentn(actual coordinates)')
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
fig.colorbar(im2, ax=ax2, shrink=0.8)
plt.show()
import numpy as np
# 创建 50x50 的数学函数数据
x = np.linspace(-3, 3, 50)
y = np.linspace(-3, 3, 50)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5),
layout='constrained')
# 左图:不使用 extent,轴坐标为像素索引
im1 = ax1.imshow(Z, cmap='RdYlBu', origin='lower')
ax1.set_title('Without extentn(pixel indices)')
fig.colorbar(im1, ax=ax1, shrink=0.8)
# 右图:使用 extent,轴坐标为实际数据坐标
im2 = ax2.imshow(Z, cmap='RdYlBu', origin='lower',
extent=[-3, 3, -3, 3]) # [xmin, xmax, ymin, ymax]
ax2.set_title('With extentn(actual coordinates)')
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
fig.colorbar(im2, ax=ax2, shrink=0.8)
plt.show()
示例 3:不同插值方法对比
实例
import matplotlib.pyplot as plt
import numpy as np
# 创建一个小尺寸数据(10x10),放大显示来体现插值差异
data = np.random.rand(10, 10)
interpolations = ['none', 'nearest', 'bilinear', 'bicubic',
'spline16', 'spline36', 'lanczos']
# lanczos has been renamed - use 'lanczos' instead
fig, axes = plt.subplots(2, 3, figsize=(12, 8),
layout='constrained')
axes = axes.flatten()
for ax, interp in zip(axes, interpolations):
im = ax.imshow(data, cmap='viridis', interpolation=interp)
ax.set_title(f'interpolation="{interp}"')
ax.set_xticks([])
ax.set_yticks([])
# 隐藏最后一个多余的子图
axes[-1].set_visible(False)
fig.suptitle('Comparison of Interpolation Methods', fontsize=14)
plt.show()
import numpy as np
# 创建一个小尺寸数据(10x10),放大显示来体现插值差异
data = np.random.rand(10, 10)
interpolations = ['none', 'nearest', 'bilinear', 'bicubic',
'spline16', 'spline36', 'lanczos']
# lanczos has been renamed - use 'lanczos' instead
fig, axes = plt.subplots(2, 3, figsize=(12, 8),
layout='constrained')
axes = axes.flatten()
for ax, interp in zip(axes, interpolations):
im = ax.imshow(data, cmap='viridis', interpolation=interp)
ax.set_title(f'interpolation="{interp}"')
ax.set_xticks([])
ax.set_yticks([])
# 隐藏最后一个多余的子图
axes[-1].set_visible(False)
fig.suptitle('Comparison of Interpolation Methods', fontsize=14)
plt.show()
示例 4:显示真实图像 (RGB)
实例
import matplotlib.pyplot as plt
import numpy as np
# 创建一个 "渐变" 图像(模拟 RGB 图像)
# 高度 100,宽度 200,3 个颜色通道
height, width = 100, 200
image = np.zeros((height, width, 3))
# R 通道:从左到右递增
image[:, :, 0] = np.linspace(0, 1, width)
# G 通道:从下到上递增
image[:, :, 1] = np.linspace(0, 1, height).reshape(-1, 1)
# B 通道:对角线方向渐变
image[:, :, 2] = np.sin(np.linspace(0, 4*np.pi, width)) * 0.5 + 0.5
fig, ax = plt.subplots(figsize=(8, 4), layout='constrained')
# 3D 数组 (M,N,3) 自动识别为 RGB 图像,无需 cmap
ax.imshow(image)
ax.set_title('Synthetic RGB Image')
ax.set_xlabel('Width (pixels)')
ax.set_ylabel('Height (pixels)')
plt.show()
print("runoob: image displayed")
import numpy as np
# 创建一个 "渐变" 图像(模拟 RGB 图像)
# 高度 100,宽度 200,3 个颜色通道
height, width = 100, 200
image = np.zeros((height, width, 3))
# R 通道:从左到右递增
image[:, :, 0] = np.linspace(0, 1, width)
# G 通道:从下到上递增
image[:, :, 1] = np.linspace(0, 1, height).reshape(-1, 1)
# B 通道:对角线方向渐变
image[:, :, 2] = np.sin(np.linspace(0, 4*np.pi, width)) * 0.5 + 0.5
fig, ax = plt.subplots(figsize=(8, 4), layout='constrained')
# 3D 数组 (M,N,3) 自动识别为 RGB 图像,无需 cmap
ax.imshow(image)
ax.set_title('Synthetic RGB Image')
ax.set_xlabel('Width (pixels)')
ax.set_ylabel('Height (pixels)')
plt.show()
print("runoob: image displayed")
示例 5:对数归一化
实例
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LogNorm
# 创建跨度很大的数据
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X**2 + Y**2) / 2) * 1000 # 高斯函数,值从 0 到 1000
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5),
layout='constrained')
# 左图:线性归一化(默认)
im1 = ax1.imshow(Z, cmap='hot')
ax1.set_title('Linear Normalization')
fig.colorbar(im1, ax=ax1, shrink=0.8)
# 右图:对数归一化(LogNorm)
im2 = ax2.imshow(Z, cmap='hot', norm=LogNorm())
ax2.set_title('Log Normalization (LogNorm)')
fig.colorbar(im2, ax=ax2, shrink=0.8)
fig.suptitle('Linear vs Log Normalization', fontsize=14)
plt.show()
import numpy as np
from matplotlib.colors import LogNorm
# 创建跨度很大的数据
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X**2 + Y**2) / 2) * 1000 # 高斯函数,值从 0 到 1000
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5),
layout='constrained')
# 左图:线性归一化(默认)
im1 = ax1.imshow(Z, cmap='hot')
ax1.set_title('Linear Normalization')
fig.colorbar(im1, ax=ax1, shrink=0.8)
# 右图:对数归一化(LogNorm)
im2 = ax2.imshow(Z, cmap='hot', norm=LogNorm())
ax2.set_title('Log Normalization (LogNorm)')
fig.colorbar(im2, ax=ax2, shrink=0.8)
fig.suptitle('Linear vs Log Normalization', fontsize=14)
plt.show()
常见问题
origin='upper' 和 'lower' 的区别?
origin='upper'(默认):数组 [0, 0] 在左上角,y 轴从上到下,适合图像。
origin='lower':数组 [0, 0] 在左下角,y 轴从下到上,适合数学/科学数据。
可通过 plt.rcParams['image.origin'] = 'lower' 全局修改默认行为。
imshow vs pcolormesh 如何选择?
imshow() 适合规则网格、大数据量、快速渲染(基于光栅化)。
pcolormesh() 适合不规则网格、需要精确的网格边界(基于矢量绘制)。
如何显示灰度图像?
设置 cmap='gray' 或 cmap='Greys_r'(灰度反转)。

Matplotlib 参考文档