Matplotlib绘制等高线和填充等高线图:全面指南
Matplotlib是Python中最流行的数据可视化库之一,它提供了强大的绘图功能,包括绘制等高线和填充等高线图。本文将详细介绍如何使用Matplotlib的contour和contourf函数来创建这些图形,并提供多个示例代码来帮助您掌握这些技术。
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('Simple Contour Plot - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
Output:
这个例子创建了一个简单的等高线图。我们首先生成了一个二维网格,然后计算了Z值。contour()
函数使用这些数据绘制等高线。
2. 填充等高线图
填充等高线图是等高线图的一种变体,其中等高线之间的区域被填充颜色。这种图形可以更直观地展示数据的变化。使用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.contourf(X, Y, Z)
plt.title('Filled Contour Plot - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.colorbar(label='Z')
plt.show()
Output:
在这个例子中,我们使用了contourf()
函数来创建填充等高线图。注意我们还添加了一个颜色条,它显示了不同颜色对应的Z值。
3. 自定义等高线级别
默认情况下,Matplotlib会自动选择等高线的级别。但有时我们可能想要自定义这些级别。可以通过向contour()
或contourf()
函数传递一个levels参数来实现:
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))
levels = np.linspace(-1, 1, 11)
plt.contourf(X, Y, Z, levels=levels)
plt.contour(X, Y, Z, levels=levels, colors='k', linewidths=0.5)
plt.title('Custom Contour Levels - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.colorbar(label='Z')
plt.show()
Output:
在这个例子中,我们定义了11个等高线级别,从-1到1。我们同时使用了contourf()
和contour()
函数,前者创建填充等高线,后者在填充区域上添加黑色轮廓线。
4. 设置等高线颜色
Matplotlib提供了多种方式来自定义等高线的颜色。我们可以使用预定义的颜色映射,或者自定义颜色:
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.contourf(X, Y, Z, cmap='coolwarm')
plt.title('Custom Colormap - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.colorbar(label='Z')
plt.show()
Output:
在这个例子中,我们使用了’coolwarm’颜色映射。Matplotlib提供了许多内置的颜色映射,如’viridis’、’plasma’、’inferno’等。
5. 添加等高线标签
为了更好地理解等高线图,我们可以为等高线添加标签:
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))
CS = plt.contour(X, Y, Z)
plt.clabel(CS, inline=True, fontsize=10)
plt.title('Contour Plot with Labels - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
Output:
clabel()
函数用于添加等高线标签。inline=True
参数确保标签被放置在等高线内部。
6. 结合等高线图和其他图形
Matplotlib允许我们将等高线图与其他类型的图形结合起来。例如,我们可以在等高线图上添加散点图:
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.contourf(X, Y, Z, alpha=0.8)
plt.scatter(X[::10, ::10], Y[::10, ::10], c='red', s=10)
plt.title('Contour Plot with Scatter - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.colorbar(label='Z')
plt.show()
Output:
在这个例子中,我们首先绘制了填充等高线图,然后在其上添加了散点图。alpha=0.8
参数使填充等高线略微透明,以便更好地看到散点。
7. 3D等高线图
虽然等高线图通常用于在2D平面上表示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=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.contour(X, Y, Z)
ax.set_title('3D Contour Plot - how2matplotlib.com')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
Output:
这个例子使用了Matplotlib的3D工具包来创建3D等高线图。注意我们需要导入Axes3D
并设置projection='3d'
。
8. 等高线图的插值
有时,我们的数据可能不是在规则网格上定义的。在这种情况下,我们可以使用插值来创建等高线图:
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))
plt.contourf(Xi, Yi, Zi)
plt.scatter(x, y, c='k', s=1, alpha=0.1)
plt.title('Interpolated Contour Plot - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.colorbar(label='Z')
plt.show()
Output:
在这个例子中,我们首先生成了一些随机数据点。然后,我们使用SciPy的griddata
函数对这些点进行插值,创建一个规则网格。最后,我们使用这个插值网格绘制等高线图,并在其上叠加原始数据点。
9. 等高线图的标准化
有时,我们可能想要标准化等高线的颜色范围。这在比较不同数据集时特别有用:
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))
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
vmin, vmax = -1, 1
im1 = ax1.contourf(X, Y, Z1, vmin=vmin, vmax=vmax)
ax1.set_title('Sin Function - how2matplotlib.com')
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
im2 = ax2.contourf(X, Y, Z2, vmin=vmin, vmax=vmax)
ax2.set_title('Cos Function - how2matplotlib.com')
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
fig.colorbar(im1, ax=[ax1, ax2], label='Z')
plt.show()
Output:
在这个例子中,我们绘制了两个不同的函数的等高线图。通过设置相同的vmin
和vmax
值,我们确保两个图使用相同的颜色范围,使它们可以直接比较。
10. 等高线图的平滑处理
有时,我们可能想要平滑等高线以获得更美观的效果。这可以通过增加数据点的数量或使用插值来实现:
import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import gaussian_filter
x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 50)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
Z_smooth = gaussian_filter(Z, sigma=1)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
ax1.contourf(X, Y, Z)
ax1.set_title('Original - how2matplotlib.com')
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax2.contourf(X, Y, Z_smooth)
ax2.set_title('Smoothed - how2matplotlib.com')
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
plt.show()
Output:
在这个例子中,我们使用SciPy的gaussian_filter
函数来平滑数据。左图显示原始等高线图,右图显示平滑后的等高线图。
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)
Z = np.sin(np.sqrt(X**2 + Y**2))
plt.figure(figsize=(10, 8))
levels = [-0.75, -0.25, 0.25, 0.75]
plt.contourf(X, Y, Z, levels=levels, colors=['blue', 'green', 'yellow', 'red'])
plt.colorbar(ticks=levels)
plt.title('Discretized Contour Plot - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
Output:
在这个例子中,我们定义了四个离散的级别,并为每个级别分配了不同的颜色。这种方法可以用于将连续数据分类为离散类别。
12. 等高线图的动画
Matplotlib还支持创建动画等高线图。这对于展示随时间变化的数据特别有用:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
fig, ax = plt.subplots(figsize=(10, 8))
def animate(i):
Z = np.sin(np.sqrt(X**2 + Y**2) - 0.1 * i)
ax.clear()
ax.contourf(X, Y, Z)
ax.set_title(f'Frame {i} - how2matplotlib.com')
ax.set_xlabel('X')
ax.set_ylabel('Y')
anim = FuncAnimation(fig, animate, frames=50, interval=100)
plt.show()
Output:
这个例子创建了一个动画等高线图,展示了随时间变化的正弦函数。FuncAnimation
函数用于创建动画,animate
函数定义了每一帧的内容。
13. 等高线图的极坐标表示
虽然我们通常在笛卡尔坐标系中绘制等高线图,但有时在极坐标系中绘制可能更有意义:
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 * np.sin(Theta)
fig, ax = plt.subplots(subplot_kw=dict(projection='polar'), figsize=(10, 8))
ax.contourf(Theta, R, Z)
ax.set_title('Polar Contour Plot - how2matplotlib.com')
plt.show()
Output:
这个例子在极坐标系中创建了等高线图。注意我们使用subplot_kw=dict(projection='polar')
来设置极坐标系。
14. 等高线图的对数刻度
对于跨越多个数量级的数据,使用对数刻度可能更合适:
import numpy as np
import matplotlib.pyplot as plt
x = np.logspace(0, 2, 100)
y = np.logspace(0, 2, 100)
X, Y = np.meshgrid(x, y)
Z = np.log10(X * Y)
plt.figure(figsize=(10, 8))
plt.contourf(X, Y, Z)
plt.xscale('log')
plt.yscale('log')
plt.title('Log-scale Contour Plot - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.colorbar(label='log10(Z)')
plt.show()
Output:
这个例子创建了一个具有对数刻度的等高线图。我们使用np.logspace
生成对数间隔的数据,并使用plt.xscale('log')
和plt.yscale('log')
设置对数刻度。
15. 等高线图的不规则网格
有时,我们的数据可能在不规则的网格上。Matplotlib也可以处理这种情况:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.tri import Triangulation
# 生成不规则网格
np.random.seed(0)
x = np.random.uniform(-2, 2, 1000)
y = np.random.uniform(-2, 2, 1000)
z = np.sin(x) * np.cos(y)
# 创建三角剖分
triang = Triangulation(x, y)
plt.figure(figsize=(10, 8))
plt.tricontourf(triang, z)
plt.title('Contour Plot on Irregular Grid - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.colorbar(label='Z')
plt.show()
Output:
这个例子使用Triangulation
类来处理不规则网格数据。tricontourf
函数用于在这种不规则网格上绘制填充等高线图。
16. 等高线图的遮罩
有时,我们可能想要在等高线图的某些区域不显示数据。这可以通过使用遮罩来实现:
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))
# 创建遮罩
mask = np.sqrt(X**2 + Y**2) > 4
# 应用遮罩
Z_masked = np.ma.array(Z, mask=mask)
plt.figure(figsize=(10, 8))
plt.contourf(X, Y, Z_masked)
plt.title('Masked Contour Plot - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.colorbar(label='Z')
plt.show()
Output:
在这个例子中,我们创建了一个圆形遮罩,使得半径大于4的区域不显示数据。
17. 等高线图的颜色映射反转
有时,我们可能想要反转颜色映射,使得高值对应冷色,低值对应暖色:
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.contourf(X, Y, Z, cmap='coolwarm_r')
plt.title('Reversed Colormap Contour Plot - how2matplotlib.com')
plt.xlabel('X')
plt.ylabel('Y')
plt.colorbar(label='Z')
plt.show()
Output:
在这个例子中,我们使用了’coolwarm_r’颜色映射,其中’_r’后缀表示反转颜色映射。
18. 等高线图的多子图
当我们需要比较多个相关的等高线图时,使用多子图布局可能会很有用:
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)
fig, axs = plt.subplots(2, 2, figsize=(15, 15))
Z1 = np.sin(np.sqrt(X**2 + Y**2))
axs[0, 0].contourf(X, Y, Z1)
axs[0, 0].set_title('Sin Function - how2matplotlib.com')
Z2 = np.cos(np.sqrt(X**2 + Y**2))
axs[0, 1].contourf(X, Y, Z2)
axs[0, 1].set_title('Cos Function - how2matplotlib.com')
Z3 = np.exp(-(X**2 + Y**2))
axs[1, 0].contourf(X, Y, Z3)
axs[1, 0].set_title('Gaussian Function - how2matplotlib.com')
Z4 = X * np.exp(-X**2 - Y**2)
im = axs[1, 1].contourf(X, Y, Z4)
axs[1, 1].set_title('Modified Gaussian - how2matplotlib.com')
fig.colorbar(im, ax=axs.ravel().tolist())
plt.tight_layout()
plt.show()
Output:
这个例子创建了一个2×2的子图布局,每个子图显示不同的函数的等高线图。
总结
Matplotlib的contour和contourf函数提供了强大而灵活的工具来创建等高线图和填充等高线图。通过本文介绍的各种技术,您可以自定义等高线级别、颜色、标签等,以及处理不规则数据、创建动画等高线图,甚至在3D空间中绘制等高线。这些技术可以帮助您更有效地可视化和分析复杂的二维数据。无论您是在进行科学研究、数据分析还是创建信息图表,掌握这些技巧都将大大提升您的数据可视化能力。