Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

参考:Make filled polygons between two curves in Python using Matplotlib

Matplotlib是Python中强大的数据可视化库,它提供了丰富的绘图功能。本文将详细介绍如何使用Matplotlib在两条曲线之间创建填充多边形,这是一种常用的数据可视化技术,可以有效地展示两个数据集之间的差异或关系。我们将通过多个示例来探讨不同的实现方法和自定义选项,帮助您掌握这一技巧。

1. 基础概念和准备工作

在开始绘制填充多边形之前,我们需要了解一些基本概念并做好准备工作。

1.1 什么是填充多边形?

填充多边形是指在两条曲线之间的区域用颜色或图案填充的图形。这种技术常用于展示数据范围、误差区间或两个数据集之间的差异。

1.2 环境设置

首先,确保您已经安装了Matplotlib库。如果没有,可以使用以下命令安装:

pip install matplotlib

1.3 导入必要的库

在开始绘图之前,我们需要导入Matplotlib库。通常,我们会使用以下方式导入:

import matplotlib.pyplot as plt
import numpy as np

这里我们同时导入了NumPy库,因为我们经常需要使用它来生成数据。

2. 基本的填充多边形绘制

让我们从一个简单的例子开始,展示如何在两条曲线之间创建填充多边形。

import matplotlib.pyplot as plt
import numpy as np

# 生成数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

# 创建图形和坐标轴
fig, ax = plt.subplots()

# 绘制两条曲线
ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')

# 填充两条曲线之间的区域
ax.fill_between(x, y1, y2, alpha=0.3)

# 设置标题和标签
ax.set_title('Filled Area Between Sin and Cos Curves - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

# 显示图形
plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

在这个例子中,我们首先生成了两组数据:sin(x)cos(x)。然后,我们使用plot()函数绘制这两条曲线,并使用fill_between()函数填充它们之间的区域。alpha参数用于设置填充区域的透明度。

3. 自定义填充颜色和样式

Matplotlib提供了多种方式来自定义填充区域的外观。让我们探索一些常用的选项。

3.1 设置填充颜色

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')

# 使用自定义颜色填充
ax.fill_between(x, y1, y2, color='lightgreen', alpha=0.5)

ax.set_title('Custom Color Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

在这个例子中,我们使用color参数设置了填充区域的颜色为浅绿色。

3.2 使用渐变填充

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')

# 创建自定义颜色映射
colors = ['blue', 'white', 'red']
n_bins = 100
cmap = LinearSegmentedColormap.from_list('custom', colors, N=n_bins)

# 使用颜色映射填充
ax.fill_between(x, y1, y2, cmap=cmap, alpha=0.5)

ax.set_title('Gradient Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

这个例子展示了如何使用颜色映射创建渐变填充效果。我们首先创建了一个自定义的颜色映射,然后将其应用到fill_between()函数中。

4. 条件填充

有时我们可能只想填充满足特定条件的区域。Matplotlib的fill_between()函数允许我们指定填充条件。

4.1 基于y值的条件填充

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')

# 只填充y1 > y2的区域
ax.fill_between(x, y1, y2, where=(y1 > y2), alpha=0.3, color='green')

# 只填充y1 < y2的区域
ax.fill_between(x, y1, y2, where=(y1 < y2), alpha=0.3, color='red')

ax.set_title('Conditional Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

在这个例子中,我们使用where参数指定了填充条件。绿色区域表示sin(x) > cos(x)的部分,红色区域表示sin(x) < cos(x)的部分。

4.2 基于x值的条件填充

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')

# 只填充x < 5的区域
ax.fill_between(x, y1, y2, where=(x < 5), alpha=0.3, color='purple')

ax.set_title('X-based Conditional Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

这个例子展示了如何基于x值进行条件填充。我们只填充了x < 5的区域。

5. 多区域填充

有时我们可能需要在同一图表中填充多个区域。Matplotlib允许我们轻松地实现这一点。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')
ax.plot(x, y3, label='tan(x)')

# 填充sin(x)和cos(x)之间的区域
ax.fill_between(x, y1, y2, alpha=0.3, color='green', label='sin-cos')

# 填充cos(x)和tan(x)之间的区域
ax.fill_between(x, y2, y3, alpha=0.3, color='red', label='cos-tan')

ax.set_title('Multiple Area Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

# 限制y轴范围以便更好地查看
ax.set_ylim(-2, 2)

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

在这个例子中,我们绘制了三条曲线,并填充了它们之间的两个区域。注意我们如何使用不同的颜色和标签来区分这些区域。

6. 堆叠区域图

堆叠区域图是另一种常见的可视化类型,它可以用来展示多个数据系列的累积效果。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.sin(x) + 0.5
y3 = np.sin(x) + 1

fig, ax = plt.subplots()

ax.fill_between(x, 0, y1, alpha=0.3, label='Area 1')
ax.fill_between(x, y1, y2, alpha=0.3, label='Area 2')
ax.fill_between(x, y2, y3, alpha=0.3, label='Area 3')

ax.set_title('Stacked Area Plot - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

这个例子创建了一个堆叠区域图,展示了三个区域的累积效果。注意我们如何通过改变fill_between()的参数来创建堆叠效果。

7. 使用网格和阴影

为了增强图表的可读性和美观性,我们可以添加网格线和阴影效果。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')

# 添加网格
ax.grid(True, linestyle='--', alpha=0.7)

# 使用阴影效果填充
ax.fill_between(x, y1, y2, alpha=0.3, color='purple', 
                edgecolor='darkpurple', hatch='///')

ax.set_title('Fill with Grid and Shadow - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

在这个例子中,我们添加了网格线并使用了阴影效果来填充区域。hatch参数用于创建阴影图案,edgecolor参数设置边缘颜色。

8. 动态填充

有时我们可能需要根据数据动态地调整填充区域。下面是一个简单的例子,展示如何根据数据的变化来填充区域。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.zeros_like(x)

fig, ax = plt.subplots()

line, = ax.plot(x, y1, label='sin(x)')
fill = ax.fill_between(x, y1, y2, alpha=0.3, color='green')

ax.set_title('Dynamic Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

for i in range(100):
    y2 = np.cos(x + i/10)
    line.set_ydata(y2)
    fill.remove()
    fill = ax.fill_between(x, y1, y2, alpha=0.3, color='green')
    plt.pause(0.1)

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

这个例子创建了一个动画效果,展示了如何动态地更新填充区域。注意我们如何在每次迭代中移除旧的填充并创建新的填充。

9. 3D填充

Matplotlib还支持在3D图表中创建填充区域。让我们看一个简单的例子。

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

x = np.linspace(0, 10, 100)
y = np.linspace(0, 10, 100)
X, Y = np.meshgrid(x, y)

Z1 = np.sin(X) + np.cos(Y)
Z2 = np.zeros_like(Z1)

ax.plot_surface(X, Y, Z1, alpha=0.5)
ax.plot_surface(X, Y, Z2, alpha=0.5)

# 填充两个曲面之间的区域
ax.add_collection3d(plt.fill_between(x, np.min(Z1), np.max(Z1), 
                                     alpha=0.3, color='green'), zs=0, zdir='y')

ax.set_title('3D Fill - how2matplotlib.com')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

这个例子展示了如何在3D图表中创建填充区域。我们使用plot_surface()函数绘制两个曲面,然后使用fill_between()add_collection3d()在它们之间创建填充区域。

10. 自定义图例

当我们创建复杂的填充图时,自定义图例可以帮助更好地解释数据。

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Patch

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')

# 创建填充区域
fill1 = ax.fill_between(x, y1, y2, where=(y1 > y2), alpha=0.3, color='green')
fill2 = ax.fill_between(x, y1, y2, where=(y1 <= y2), alpha=0.3, color='red')

# 创建自定义图例
legend_elements = [
    Patch(facecolor='green', edgecolor='green', alpha=0.3, label='sin(x) > cos(x)'),
    Patch(facecolor='red', edgecolor='red', alpha=0.3, label='sin(x) <= cos(x)')
]

ax.legend(handles=legend_elements)

ax.set_title('Custom Legend - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

在这个例子中,我们使用Patch对象创建了自定义的图例项,以更好地解释填充区域的含义。

11. 使用极坐标系

Matplotlib不仅支持在笛卡尔坐标系中创建填充区域,还支持在极坐标系中进行填充。

import matplotlib.pyplot as plt
import numpy as np

theta = np.linspace(0, 2*np.pi, 100)
r1 = 0.5 + np.cos(theta)
r2 = 1 + 0.5 * np.sin(theta)

fig, ax = plt.subplots(subplot_kw=dict(projection='polar'))

ax.plot(theta, r1)
ax.plot(theta, r2)
ax.fill_between(theta, r1, r2, alpha=0.3)

ax.set_title('Polar Fill - how2matplotlib.com')
ax.set_rticks([0.5, 1, 1.5])

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

这个例子展示了如何在极坐标系中创建填充区域。我们使用subplot_kw=dict(projection='polar')来创建极坐标图,然后使用fill_between()函数填充两条曲线之间的区域。

12. 填充不连续数据

有时我们可能需要处理不连续的数据。Matplotlib可以很好地处理这种情况。

import matplotlib.pyplot as plt
import numpy as np

x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
y1 = np.array([1, 2, np.nan, 4, 5, 6, np.nan, 8, 9, 10])
y2 = np.array([0, 1, 2, 3, 4, np.nan, 6, 7, 8, 9])

fig, ax = plt.subplots()

ax.plot(x, y1, label='Data 1')
ax.plot(x, y2, label='Data 2')

ax.fill_between(x, y1, y2, where=~np.isnan(y1) & ~np.isnan(y2), 
                alpha=0.3, interpolate=True)

ax.set_title('Fill with Discontinuous Data - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

在这个例子中,我们使用了包含NaN值的数据。fill_between()函数的where参数用于指定只在非NaN值之间填充,interpolate=True参数用于在缺失数据点之间进行插值。

13. 使用步进填充

对于某些类型的数据,使用步进填充可能更合适。Matplotlib提供了这种功能。

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0, 10, 1)
y1 = np.random.randint(0, 10, 10)
y2 = np.random.randint(0, 10, 10)

fig, ax = plt.subplots()

ax.step(x, y1, label='Data 1')
ax.step(x, y2, label='Data 2')

ax.fill_between(x, y1, y2, step='pre', alpha=0.3)

ax.set_title('Step Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

这个例子展示了如何创建步进填充图。我们使用step()函数绘制步进线,然后使用fill_between()函数的step参数创建步进填充。

14. 使用样条插值

对于某些数据集,使用样条插值可以创建更平滑的填充区域。

import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import make_interp_spline

x = np.array([0, 1, 2, 3, 4, 5])
y1 = np.array([1, 3, 4, 2, 5, 3])
y2 = np.array([0, 2, 1, 3, 2, 4])

x_smooth = np.linspace(x.min(), x.max(), 300)
spl1 = make_interp_spline(x, y1, k=3)
spl2 = make_interp_spline(x, y2, k=3)
y1_smooth = spl1(x_smooth)
y2_smooth = spl2(x_smooth)

fig, ax = plt.subplots()

ax.plot(x_smooth, y1_smooth, label='Data 1')
ax.plot(x_smooth, y2_smooth, label='Data 2')

ax.fill_between(x_smooth, y1_smooth, y2_smooth, alpha=0.3)

ax.set_title('Spline Interpolation Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

在这个例子中,我们使用SciPy的make_interp_spline函数创建了平滑的插值曲线,然后使用这些平滑曲线来创建填充区域。

15. 使用对数刻度

在某些情况下,使用对数刻度可能更适合展示数据。Matplotlib允许我们在填充图中使用对数刻度。

import matplotlib.pyplot as plt
import numpy as np

x = np.logspace(0, 2, 100)
y1 = np.log(x)
y2 = np.sqrt(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label='log(x)')
ax.plot(x, y2, label='sqrt(x)')

ax.fill_between(x, y1, y2, alpha=0.3)

ax.set_xscale('log')
ax.set_yscale('log')

ax.set_title('Log Scale Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

plt.show()

Output:

Matplotlib绘制两条曲线之间的填充多边形:详细教程与实例

这个例子展示了如何在对数刻度上创建填充区域。我们使用set_xscale('log')set_yscale('log')来设置坐标轴的对数刻度。

16. 使用颜色映射进行填充

我们可以使用颜色映射来创建更复杂的填充效果。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()

ax.plot(x, y1, label='sin(x)')
ax.plot(x, y2, label='cos(x)')

# 使用颜色映射填充
norm = plt.Normalize(y2.min(), y2.max())
cmap = plt.get_cmap('viridis')
ax.fill_between(x, y1, y2, alpha=0.3, color=cmap(norm(y2)))

ax.set_title('Colormap Fill - how2matplotlib.com')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()

# 添加颜色条
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
plt.colorbar(sm)

plt.show()

这个例子展示了如何使用颜色映射来填充区域。我们使用Normalize对象和颜色映射来创建动态颜色填充,并添加了一个颜色条来解释颜色的含义。

结论

通过本文,我们详细探讨了如何使用Matplotlib在Python中创建两条曲线之间的填充多边形。我们从基本概念开始,逐步深入到更复杂的技术,包括条件填充、多区域填充、3D填充、极坐标填充等。我们还介绍了如何自定义填充的外观,如何处理不连续数据,以及如何使用高级技术如样条插值和颜色映射。

这些技术不仅可以增强数据的可视化效果,还能帮助我们更好地理解和展示数据之间的关系。无论是在科学研究、数据分析还是商业报告中,掌握这些技巧都将大大提升您的数据可视化能力。

希望这篇教程能够帮助您更好地使用Matplotlib创建填充多边形,并在您的数据可视化项目中发挥作用。记住,实践是掌握这些技能的关键,所以不要犹豫,立即开始尝试这些例子,并将它们应用到您自己的数据中!

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程