Matplotlib绘制等高线图:全面指南与实例
参考:Contour Plot using Matplotlib – Python
Matplotlib是Python中最流行的数据可视化库之一,它提供了强大的工具来创建各种类型的图表,包括等高线图。等高线图是一种二维图形,用于表示三维数据,特别适合展示地形、温度分布、压力场等连续变化的数据。本文将深入探讨如何使用Matplotlib绘制等高线图,并提供多个实用示例。
1. 等高线图基础
等高线图的基本原理是在二维平面上用曲线连接具有相同值的点。这些曲线被称为等高线,每条线代表一个特定的数值。在Matplotlib中,我们主要使用contour()
和contourf()
函数来创建等高线图。
让我们从一个简单的例子开始:
import numpy as np
import matplotlib.pyplot as plt
# 创建数据
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))
# 绘制等高线图
plt.figure(figsize=(10, 8))
plt.contour(X, Y, Z)
plt.title('How2matplotlib.com: Simple Contour Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
在这个例子中,我们首先创建了一个网格数据,然后使用contour()
函数绘制等高线。X
和Y
是网格坐标,Z
是对应的函数值。
2. 填充等高线图
除了线条等高线,我们还可以创建填充的等高线图,这种图形更能直观地展示数值的变化。使用contourf()
函数可以实现这一效果:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X**2 + Y**2))
plt.figure(figsize=(10, 8))
plt.contourf(X, Y, Z, levels=20, cmap='viridis')
plt.colorbar(label='Z value')
plt.title('How2matplotlib.com: Filled Contour Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个例子展示了如何创建填充的等高线图。我们使用contourf()
函数,并指定了颜色映射和等高线的数量。colorbar()
函数添加了一个颜色条,显示数值和颜色的对应关系。
3. 自定义等高线级别
在绘制等高线图时,我们可以自定义等高线的级别,即指定在哪些值处绘制等高线:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = X**2 + Y**2
plt.figure(figsize=(10, 8))
levels = [1, 5, 10, 20, 30, 40, 50]
cs = plt.contour(X, Y, Z, levels=levels)
plt.clabel(cs, inline=True, fontsize=10)
plt.title('How2matplotlib.com: Contour Plot with Custom Levels')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
在这个例子中,我们通过levels
参数指定了等高线的具体值。clabel()
函数用于在等高线上添加标签,显示对应的数值。
4. 等高线图与颜色映射
颜色映射可以增强等高线图的视觉效果,帮助更好地理解数据分布:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
plt.figure(figsize=(10, 8))
cs = plt.contourf(X, Y, Z, cmap='coolwarm', levels=20)
plt.colorbar(cs, label='Z value')
plt.contour(X, Y, Z, colors='black', linewidths=0.5, levels=20)
plt.title('How2matplotlib.com: Contour Plot with Color Mapping')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个例子展示了如何结合填充等高线和线条等高线,并使用coolwarm
颜色映射。黑色线条增强了等高线的清晰度。
5. 3D等高线图
Matplotlib还支持创建3D等高线图,这可以更直观地展示数据的三维特性:
import numpy as np
import matplotlib.pyplot as plt
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, 8))
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(X, Y, Z, cmap='viridis')
contour = ax.contour(X, Y, Z, zdir='z', offset=-2, cmap='coolwarm')
fig.colorbar(surf, shrink=0.5, aspect=5)
ax.set_title('How2matplotlib.com: 3D Contour Plot')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_zlabel('Z-axis')
plt.show()
Output:
这个例子创建了一个3D表面图,并在底部添加了等高线投影。plot_surface()
函数用于绘制3D表面,而contour()
函数在z轴的特定位置添加了等高线。
6. 等高线图标签
为等高线添加标签可以提供更多信息:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = X*np.exp(-X**2 - Y**2)
plt.figure(figsize=(10, 8))
cs = plt.contour(X, Y, Z, levels=10)
plt.clabel(cs, inline=True, fontsize=10, fmt='%1.2f')
plt.title('How2matplotlib.com: Contour Plot with Labels')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个例子使用clabel()
函数为等高线添加了标签。fmt
参数指定了标签的格式。
7. 不规则数据的等高线图
有时我们需要处理不规则分布的数据点:
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
# 生成随机数据点
np.random.seed(0)
x = np.random.rand(1000) * 4 - 2
y = np.random.rand(1000) * 4 - 2
z = x*np.exp(-x**2 - y**2)
# 创建网格
xi = np.linspace(-2, 2, 100)
yi = np.linspace(-2, 2, 100)
Xi, Yi = np.meshgrid(xi, yi)
# 插值
Zi = griddata((x, y), z, (Xi, Yi), method='cubic')
plt.figure(figsize=(10, 8))
cs = plt.contourf(Xi, Yi, Zi, levels=15, cmap='viridis')
plt.colorbar(cs)
plt.scatter(x, y, c='k', s=1, alpha=0.1)
plt.title('How2matplotlib.com: Contour Plot with Irregular Data')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个例子展示了如何处理不规则分布的数据点。我们使用scipy.interpolate.griddata
函数进行插值,然后绘制等高线图。
8. 等高线图与图像结合
等高线图可以与其他类型的图表结合,例如与图像叠加:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
plt.figure(figsize=(10, 8))
plt.imshow(Z, extent=[-5, 5, -5, 5], origin='lower', cmap='viridis', alpha=0.5)
cs = plt.contour(X, Y, Z, colors='white', levels=15)
plt.clabel(cs, inline=True, fontsize=8, fmt='%1.1f')
plt.colorbar(label='Z value')
plt.title('How2matplotlib.com: Contour Plot Overlaid on Image')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个例子展示了如何将等高线图叠加在图像上。imshow()
函数用于显示底层图像,而contour()
函数添加了等高线。
9. 极坐标等高线图
Matplotlib还支持在极坐标系中绘制等高线图:
import numpy as np
import matplotlib.pyplot as plt
r = np.linspace(0, 2, 100)
theta = np.linspace(0, 2*np.pi, 100)
R, Theta = np.meshgrid(r, theta)
Z = R**2 * (1 - R/2) * np.cos(Theta)
fig, ax = plt.subplots(subplot_kw=dict(projection='polar'), figsize=(10, 8))
cs = ax.contourf(Theta, R, Z, levels=20, cmap='viridis')
plt.colorbar(cs)
ax.set_title('How2matplotlib.com: Polar Contour Plot')
plt.show()
Output:
这个例子展示了如何在极坐标系中创建等高线图。我们使用subplot_kw=dict(projection='polar')
来设置极坐标系。
10. 等高线图与散点图结合
等高线图可以与散点图结合,用于展示数据点的分布和整体趋势:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X**2 + Y**2))
# 生成随机数据点
np.random.seed(0)
x_points = np.random.uniform(-3, 3, 50)
y_points = np.random.uniform(-3, 3, 50)
z_points = np.exp(-(x_points**2 + y_points**2))
plt.figure(figsize=(10, 8))
cs = plt.contourf(X, Y, Z, levels=20, cmap='viridis', alpha=0.7)
plt.colorbar(cs, label='Z value')
plt.scatter(x_points, y_points, c=z_points, cmap='viridis', edgecolors='w')
plt.title('How2matplotlib.com: Contour Plot with Scatter Points')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个例子展示了如何将散点图叠加在等高线图上。散点的颜色与等高线的颜色映射相匹配,提供了数据点与整体分布的直观对比。
11. 多子图等高线图
在某些情况下,我们可能需要在一个图形中展示多个等高线图:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z1 = np.sin(np.sqrt(X**2 + Y**2))
Z2 = np.cos(np.sqrt(X**2 + Y**2))
Z3 = X * np.exp(-X**2 - Y**2)
Z4 = Y * np.exp(-X**2 - Y**2)
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 10))
cs1 = ax1.contourf(X, Y, Z1, levels=20, cmap='viridis')
ax1.set_title('How2matplotlib.com: Sin(r)')
fig.colorbar(cs1, ax=ax1)
cs2 = ax2.contourf(X, Y, Z2, levels=20, cmap='plasma')
ax2.set_title('How2matplotlib.com: Cos(r)')
fig.colorbar(cs2, ax=ax2)
cs3 = ax3.contourf(X, Y, Z3, levels=20, cmap='inferno')
ax3.set_title('How2matplotlib.com: X * exp(-X^2 - Y^2)')
fig.colorbar(cs3, ax=ax3)
cs4 = ax4.contourf(X, Y, Z4, levels=20, cmap='magma')
ax4.set_title('How2matplotlib.com: Y * exp(-X^2 - Y^2)')
fig.colorbar(cs4, ax=ax4)
plt.tight_layout()
plt.show()
Output:
这个例子展示了如何在一个图形中创建多个子图,每个子图都是一个不同的等高线图。这种方法非常适合比较不同数据集或同一数据集的不同特征## 12. 等高线图的动画效果
Matplotlib还支持创建动态的等高线图,这对于展示随时间变化的数据特别有用:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots(figsize=(10, 8))
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
def animate(i):
ax.clear()
Z = np.sin(np.sqrt(X**2 + Y**2) - i * 0.1)
cs = ax.contourf(X, Y, Z, levels=20, cmap='viridis')
ax.set_title(f'How2matplotlib.com: Animated Contour Plot (Frame {i})')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
return cs
anim = FuncAnimation(fig, animate, frames=100, interval=50, blit=False)
plt.show()
Output:
这个例子创建了一个动态的等高线图,展示了一个波动的表面。FuncAnimation
类用于生成动画,animate
函数在每一帧更新图形。
13. 等高线图的边界和掩码
有时我们可能只想显示数据的特定区域,或者给等高线图添加边界:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
# 创建一个圆形掩码
mask = X**2 + Y**2 <= 16
plt.figure(figsize=(10, 8))
cs = plt.contourf(X, Y, Z, levels=20, cmap='viridis', mask=~mask)
plt.colorbar(cs, label='Z value')
plt.contour(X, Y, mask, colors='red', linewidths=2)
plt.title('How2matplotlib.com: Contour Plot with Boundary')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个例子展示了如何使用掩码来限制等高线图的显示区域,并添加一个边界。mask
参数用于指定要显示的区域,而额外的contour
调用添加了红色边界。
14. 等高线图的标注
在等高线图上添加标注可以帮助突出特定的特征或区域:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
fig, ax = plt.subplots(figsize=(10, 8))
cs = ax.contourf(X, Y, Z, levels=20, cmap='viridis')
plt.colorbar(cs, label='Z value')
# 添加标注
ax.annotate('Peak', xy=(np.pi/2, 0), xytext=(3, 3),
arrowprops=dict(facecolor='black', shrink=0.05))
ax.annotate('Trough', xy=(-np.pi/2, 0), xytext=(-3, -3),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.title('How2matplotlib.com: Contour Plot with Annotations')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个例子展示了如何在等高线图上添加文本标注和箭头,指出图中的特定特征。
15. 等高线图的颜色归一化
有时我们可能需要调整等高线图的颜色映射,以更好地突出某些数值范围:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
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))
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
# 默认归一化
cs1 = ax1.contourf(X, Y, Z, levels=20, cmap='viridis')
fig.colorbar(cs1, ax=ax1, label='Z value')
ax1.set_title('How2matplotlib.com: Default Normalization')
# 自定义归一化
norm = Normalize(vmin=0.2, vmax=0.8)
cs2 = ax2.contourf(X, Y, Z, levels=20, cmap='viridis', norm=norm)
fig.colorbar(cs2, ax=ax2, label='Z value')
ax2.set_title('How2matplotlib.com: Custom Normalization')
plt.tight_layout()
plt.show()
Output:
这个例子展示了如何使用Normalize
类来自定义等高线图的颜色映射范围,以突出特定的数值区间。
16. 等高线图与向量场结合
等高线图可以与向量场结合,用于展示标量场和矢量场的关系:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 20)
y = np.linspace(-5, 5, 20)
X, Y = np.meshgrid(x, y)
Z = X*np.exp(-X**2 - Y**2)
# 计算梯度
dx, dy = np.gradient(Z)
fig, ax = plt.subplots(figsize=(10, 8))
cs = ax.contourf(X, Y, Z, levels=20, cmap='viridis')
ax.quiver(X, Y, dx, dy)
plt.colorbar(cs, label='Z value')
ax.set_title('How2matplotlib.com: Contour Plot with Vector Field')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
plt.show()
Output:
这个例子展示了如何将等高线图与向量场(在这里是梯度场)结合。quiver
函数用于绘制向量场。
17. 等高线图的对数刻度
对于跨越多个数量级的数据,使用对数刻度的等高线图可能更合适:
import numpy as np
import matplotlib.pyplot as plt
x = np.logspace(-1, 1, 100)
y = np.logspace(-1, 1, 100)
X, Y = np.meshgrid(x, y)
Z = X**2 + Y**2
fig, ax = plt.subplots(figsize=(10, 8))
cs = ax.contourf(X, Y, Z, levels=20, cmap='viridis', locator=plt.LogLocator())
plt.colorbar(cs, label='Z value')
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_title('How2matplotlib.com: Log-scale Contour Plot')
ax.set_xlabel('X-axis (log scale)')
ax.set_ylabel('Y-axis (log scale)')
plt.show()
Output:
这个例子展示了如何创建具有对数刻度的等高线图。LogLocator
用于在对数空间中均匀分布等高线。
18. 等高线图的插值
有时,我们可能需要对粗糙的数据进行插值以获得更平滑的等高线图:
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp2d
# 创建粗糙数据
x = np.linspace(-5, 5, 10)
y = np.linspace(-5, 5, 10)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
# 创建插值函数
f = interp2d(x, y, Z, kind='cubic')
# 创建更精细的网格
x_fine = np.linspace(-5, 5, 100)
y_fine = np.linspace(-5, 5, 100)
Z_fine = f(x_fine, y_fine)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
cs1 = ax1.contourf(X, Y, Z, levels=20, cmap='viridis')
ax1.set_title('How2matplotlib.com: Original Data')
fig.colorbar(cs1, ax=ax1)
cs2 = ax2.contourf(x_fine, y_fine, Z_fine, levels=20, cmap='viridis')
ax2.set_title('How2matplotlib.com: Interpolated Data')
fig.colorbar(cs2, ax=ax2)
plt.tight_layout()
plt.show()
Output:
这个例子展示了如何使用scipy.interpolate.interp2d
函数对粗糙数据进行插值,以获得更平滑的等高线图。
结论
Matplotlib提供了强大而灵活的工具来创建等高线图。从基本的线条等高线到填充等高线,从2D到3D,从静态图到动画,Matplotlib都能满足各种需求。通过调整颜色映射、添加标注、结合其他类型的图表等技巧,我们可以创建出既美观又信息丰富的等高线图。
在实际应用中,等高线图被广泛用于气象学、地理学、物理学等多个领域。它们可以直观地展示温度分布、压力场、地形高度等连续变化的数据。通过本文介绍的各种技巧和示例,读者应该能够根据自己的需求,使用Matplotlib创建出各种类型的等高线图。
记住,创建有效的数据可视化不仅仅是技术问题,还需要考虑数据的特性和你想传达的信息。选择合适的等高线级别、颜色映射和其他视觉元素,可以大大提高图表的可读性和信息传达效果。随着实践的增加,你将能够更好地利用Matplotlib的等高线图功能,创建出既美观又有洞察力的数据可视化作品。