Matplotlib imshow() 方法完全指南
imshow() 是 Matplotlib 中用于 显示图像、热力图、矩阵、遥感数据 的最强大函数。本教程带你从入门到 发表级 ,掌握 图像显示、热力图、颜色映射、插值、坐标轴、标注、动画、3D 表面、交互式 等全部技巧。
一、基本语法
import matplotlib.pyplot as plt
import numpy as np
# 生成随机图像数据
data = np.random.rand(10, 10)
plt.imshow(data)
plt.show()
二、核心参数详解
plt.imshow(data,
cmap='viridis', # 颜色映射
interpolation='nearest', # 插值方式
origin='lower', # 原点位置
extent=None, # 坐标轴范围 [xmin, xmax, ymin, ymax]
aspect='equal', # 纵横比
vmin=None, vmax=None,# 颜色范围
alpha=1.0) # 透明度
三、常用 cmap 颜色映射(关键!)
名称 用途 推荐场景 'viridis'默认推荐 通用,色盲友好 'plasma'高对比 热力图 'inferno'深色背景 暗色主题 'hot'黑→红→黄→白 传统热图 'coolwarm'发散数据 正负值 'seismic'发散 地震波 'gray'灰度 医学影像 'jet'彩虹 不推荐 (感知不均匀)
plt.imshow(data, cmap='plasma')
plt.colorbar(label='强度')
plt.show()
四、插值方式 interpolation
方式 效果 适用 'nearest'像素化 推荐 ,矩阵/热图'bilinear'平滑 图像缩放 'bicubic'更平滑 高质量图像 'none'无插值 原始像素
plt.imshow(data, interpolation='nearest', cmap='viridis')
五、坐标轴控制
1. extent 设置真实坐标
# 假设数据对应 x: 0~100, y: -50~50
plt.imshow(data, extent=[0, 100, -50, 50], origin='lower', cmap='hot')
plt.colorbar()
plt.xlabel('距离 (km)')
plt.ylabel('深度 (m)')
plt.show()
2. origin 控制原点
plt.imshow(data, origin='lower') # 原点在左下(图像标准)
# plt.imshow(data, origin='upper') # 原点在左上(矩阵标准)
六、真实图像显示
from matplotlib.image import imread
import requests
from io import BytesIO
# 示例:从网络加载图像
url = 'https://matplotlib.org/stable/_images/stinkbug.png'
response = requests.get(url)
img = imread(BytesIO(response.content))
plt.imshow(img)
plt.axis('off') # 隐藏坐标轴
plt.show()
七、热力图(矩阵可视化)
# 相关性矩阵示例
np.random.seed(42)
matrix = np.random.rand(8, 8)
matrix = matrix @ matrix.T # 构造对称矩阵
plt.imshow(matrix, cmap='coolwarm', vmin=-1, vmax=1)
plt.colorbar(label='相关系数')
# 添加数值
for i in range(matrix.shape[0]):
for j in range(matrix.shape[1]):
plt.text(j, i, f'{matrix[i,j]:.2f}',
ha='center', va='center', color='black', fontsize=9)
plt.xticks(range(8), [f'特征{i}' for i in range(8)])
plt.yticks(range(8), [f'特征{i}' for i in range(8)])
plt.title('特征相关性热力图')
plt.show()
八、3D 表面图(结合 imshow)
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
fig = plt.figure(figsize=(12, 5))
# 2D 热图
ax1 = fig.add_subplot(121)
im = ax1.imshow(Z, extent=[-5,5,-5,5], origin='lower', cmap='terrain')
plt.colorbar(im, ax=ax1, label='高度')
ax1.set_title('2D 热图')
# 3D 表面
ax2 = fig.add_subplot(122, projection='3d')
surf = ax2.plot_surface(X, Y, Z, cmap='terrain', alpha=0.8)
plt.colorbar(surf, ax=ax2, shrink=0.5, label='高度')
ax2.set_title('3D 表面图')
plt.tight_layout()
plt.show()
九、动画热图(动态演化)
import matplotlib.animation as animation
# 模拟时间序列数据
frames = 50
data_evolution = np.zeros((frames, 50, 50))
for t in range(frames):
x0, y0 = np.random.randint(0, 50, 2)
data_evolution[t] = np.exp(-((np.arange(50)-x0)**2 + (np.arange(50)[:, None]-y0)**2) / 100)
fig, ax = plt.subplots()
im = ax.imshow(data_evolution[0], cmap='hot', vmin=0, vmax=1)
plt.colorbar(im, label='强度')
def update(frame):
im.set_array(data_evolution[frame])
ax.set_title(f'时间步: {frame}')
return [im]
ani = animation.FuncAnimation(fig, update, frames=frames, interval=100)
# ani.save('heatmap_animation.gif', writer='pillow', fps=10)
plt.show()
十、完整专业示例(论文级)
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('seaborn-v0_8')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 生成模拟遥感数据
np.random.seed(42)
lon = np.linspace(110, 120, 200)
lat = np.linspace(30, 40, 150)
Lon, Lat = np.meshgrid(lon, lat)
# 模拟温度场
center_lon, center_lat = 115, 35
temp = 25 + 10 * np.exp(-((Lon-center_lon)**2 + (Lat-center_lat)**2) / 50)
temp += np.random.normal(0, 0.5, temp.shape) # 噪声
fig, ax = plt.subplots(figsize=(12, 8))
# 主图:温度热图
im = ax.imshow(temp, extent=[110, 120, 30, 40], origin='lower',
cmap='RdYlBu_r', interpolation='bilinear',
vmin=20, vmax=35)
cbar = plt.colorbar(im, ax=ax, shrink=0.7, pad=0.02)
cbar.set_label('温度 (°C)', fontsize=12, fontweight='bold')
# 标注城市
cities = {'北京': (116.4, 39.9), '上海': (121.5, 31.2), '广州': (113.3, 23.1)}
for city, (clon, clat) in cities.items():
ax.plot(clon, clat, 'ko', markersize=8)
ax.text(clon, clat+0.3, city, fontsize=11, fontweight='bold',
ha='center', bbox=dict(boxstyle="round", facecolor='white', alpha=0.8))
# 美化
ax.set_xlabel('经度 (°E)', fontsize=14)
ax.set_ylabel('纬度 (°N)', fontsize=14)
ax.set_title('中国东部地区温度分布模拟\n(2025年7月15日 14:00)',
fontsize=16, fontweight='bold', pad=20)
# 网格
ax.grid(True, alpha=0.3, linestyle='--', color='gray')
ax.set_facecolor('#e6f2ff')
# 小地图(inset)
ax_inset = fig.add_axes([0.68, 0.68, 0.2, 0.2])
ax_inset.imshow(temp[::10, ::10], extent=[110,120,30,40], cmap='RdYlBu_r')
ax_inset.plot(115, 35, 'r*', markersize=12, markeredgecolor='black')
ax_inset.set_title('研究区', fontsize=10)
ax_inset.tick_params(labelsize=8)
plt.tight_layout()
plt.savefig('imshow_pro.png', dpi=300, bbox_inches='tight', facecolor='white')
plt.show()
十一、imshow() 速查表(收藏用)
# 基础
plt.imshow(data)
# 热图
plt.imshow(data, cmap='viridis', interpolation='nearest')
plt.colorbar()
# 真实坐标
plt.imshow(data, extent=[xmin,xmax,ymin,ymax], origin='lower')
# 颜色范围
plt.imshow(data, vmin=0, vmax=1)
# 图像
plt.imshow(img)
plt.axis('off')
# 动画
im = ax.imshow(data[0])
def update(t): im.set_array(data[t])
# 3D 表面
ax.plot_surface(X, Y, Z, cmap='terrain')
十二、常见问题解决
问题 解决方案 图像拉伸变形 aspect='equal' 或 plt.axis('equal')颜色条太长 plt.colorbar(shrink=0.7)坐标轴反了 origin='lower'像素模糊 interpolation='nearest'保存白边 plt.savefig(..., bbox_inches='tight')
十三、推荐 cmap + interpolation 组合
用途 推荐 科学数据 cmap='viridis', interpolation='nearest'遥感影像 cmap='gray', interpolation='bilinear'热力图 cmap='hot', interpolation='nearest'发散数据 cmap='coolwarm', vmin=-1, vmax=1
十四、与 pcolormesh 对比
函数 优点 缺点 imshow快速,适合规则网格 不支持非均匀网格 pcolormesh支持非规则网格 稍慢
# 非规则网格用 pcolormesh
plt.pcolormesh(X, Y, Z, cmap='viridis', shading='auto')
官方文档
imshow API:https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.imshow.html
颜色映射:https://matplotlib.org/stable/tutorials/colors/colormaps.html
示例图库:https://matplotlib.org/stable/gallery/images_contours_and_fields/image_demo.html
总结:三步打造专业 imshow
# 1. 数据 + 坐标
im = plt.imshow(data, extent=[0,100,0,50], origin='lower',
cmap='plasma', interpolation='nearest')
# 2. 颜色条 + 标注
plt.colorbar(im, label='温度 (°C)', shrink=0.8)
plt.plot(50, 25, 'r*', markersize=12)
# 3. 美化输出
plt.xlabel('经度'); plt.ylabel('纬度')
plt.title('热力图')
plt.savefig('map.png', dpi=300, bbox_inches='tight')
一键生成热力图 :
data = np.random.rand(20, 20)
plt.imshow(data, cmap='hot', interpolation='nearest')
plt.colorbar(shrink=0.8)
plt.title('随机热图')
plt.show()
需要我为你:
生成 10种经典 imshow 模板 (遥感、矩阵、动画)?
制作 Jupyter imshow 交互小工具 (滑块切换 cmap)?
输出 LaTeX/PPT 可用代码 ?
告诉我你的需求!