如何在Matplotlib中为不同x数据的函数间区域填充颜色?
不同X数据下填充曲线围成区域的解法
当曲线使用不同的X数组时,plt.fill_between()无法直接使用,此时可以通过提取区域边界的闭合点集,再用plt.fill()来实现填充。核心步骤是:找到曲线交点确定区域顶点,按顺序拼接边界点形成闭合多边形,最后填充。
步骤说明
- 定义函数表达式:方便计算任意X处的Y值和求解交点。
- 求解曲线交点:确定围成区域的顶点坐标。
- 拼接闭合点集:沿区域边界按顺序收集所有点(包括曲线段和交点)。
- 填充区域:使用
plt.fill()填充闭合多边形。
完整代码示例
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import root # 定义各函数(修正原代码中l(x)的笔误:-40x改为-4x,否则曲线过陡无有效交点) def f(x): return np.exp(x) def g(x): return 5 * x - 1 def l(x): return -4 * x + 10 def t(x): return 3 * x + 9 # 生成原曲线的X、Y数据 x1 = np.linspace(0, 3, 100) x2 = np.linspace(0.4, 2.6, 150) x3 = np.linspace(0, 1.6, 180) x4 = np.linspace(0, 3, 125) f_y = f(x1) g_y = g(x2) l_y = l(x3) t_y = t(x4) # ---------------------- # 1. 填充四个函数围成的区域 # ---------------------- # 求解各曲线交点(区域顶点) # f(x)与l(x)的交点 sol_fl = root(lambda x: f(x) - l(x), x0=1) x_fl, y_fl = sol_fl.x[0], f(sol_fl.x[0]) # l(x)与g(x)的交点 sol_lg = root(lambda x: l(x) - g(x), x0=1) x_lg, y_lg = sol_lg.x[0], l(sol_lg.x[0]) # g(x)的终点与t(x)的对应点 x_g_end, y_g_end = x2[-1], g_y[-1] y_t_g_end = t(x_g_end) # 拼接闭合点集:f从x=0到x_fl → l从x_fl到x_lg → g从x_lg到x_g_end → t从x_g_end到x=0 → 回到起点 f_segment = x1[x1 <= x_fl], f_y[x1 <= x_fl] l_segment_x = x3[(x3 >= x_fl) & (x3 <= x_lg)] l_segment_y = l_y[(x3 >= x_fl) & (x3 <= x_lg)] g_segment_x = x2[x2 >= x_lg] g_segment_y = g_y[x2 >= x_lg] t_segment_x = x4[x4 <= x_g_end][::-1] t_segment_y = t_y[x4 <= x_g_end][::-1] fill_x = np.concatenate([f_segment[0], l_segment_x, g_segment_x, t_segment_x, [0]]) fill_y = np.concatenate([f_segment[1], l_segment_y, g_segment_y, t_segment_y, [f(0)]]) # 填充区域(半透明灰色) plt.fill(fill_x, fill_y, color='gray', alpha=0.3, label='四函数围成区域') # ---------------------- # 2. 填充f(x)与g(x)围成的区域 # ---------------------- # 求解f(x)与g(x)的两个交点 sol_fg1 = root(lambda x: f(x) - g(x), x0=0.5) x_fg1, y_fg1 = sol_fg1.x[0], f(sol_fg1.x[0]) sol_fg2 = root(lambda x: f(x) - g(x), x0=2.5) x_fg2, y_fg2 = sol_fg2.x[0], f(sol_fg2.x[0]) # 提取f在交点间的点,提取g在交点间的点并逆序(形成闭合) f_fg_x = x1[(x1 >= x_fg1) & (x1 <= x_fg2)] f_fg_y = f_y[(x1 >= x_fg1) & (x1 <= x_fg2)] g_fg_x = x2[(x2 >= x_fg1) & (x2 <= x_fg2)][::-1] g_fg_y = g_y[(x2 >= x_fg1) & (x2 <= x_fg2)][::-1] fg_fill_x = np.concatenate([f_fg_x, g_fg_x, [x_fg1]]) fg_fill_y = np.concatenate([f_fg_y, g_fg_y, [y_fg1]]) # 填充区域(半透明蓝色) plt.fill(fg_fill_x, fg_fill_y, color='blue', alpha=0.3, label='f与g围成区域') # ---------------------- # 绘制原曲线与标注 # ---------------------- plt.plot(x1, f_y, label='f(x)=e^x') plt.plot(x2, g_y, label='g(x)=5x-1') plt.plot(x3, l_y, label='l(x)=-4x+10') plt.plot(x4, t_y, label='t(x)=3x+9') plt.legend() plt.ylabel('y轴') plt.xlabel('x轴') plt.ylim(0,) plt.show()
关键细节
- 交点求解:使用
scipy.optimize.root求解函数交点,需提供合理的初始猜测值(x0)。 - 点集顺序:拼接点时必须按顺时针或逆时针顺序连接,否则填充区域会混乱。
- 曲线段提取:从原X数组中筛选出属于区域边界的部分,确保覆盖整个边界。
内容的提问来源于stack exchange,提问作者tari.k
相关产品推荐
相关产品推荐

