matplotlib中如何使用fill_between填充两个分布的交集区域
问题描述
我需要对两个概率分布曲线下的交集重叠区域进行颜色填充,目前已编写如下实现代码,但无法通过fill_between方法实现仅填充交集区域的预期效果,请问该如何正确实现?
原有问题代码
import matplotlib.pyplot as plt import numpy as np import scipy.stats as stats p1_mu = 25 p2_mu = 50 p1_sigma = 25/3 p2_sigma = p1_sigma p1 = np.linspace(p1_mu - 3 * p1_sigma, p1_mu + 3 * p1_sigma, 1000) p2 = np.linspace(p2_mu - 3 * p2_sigma, p2_mu + 3 * p2_sigma, 1000) p1_pdf = stats.norm.pdf(p1, p1_mu, p1_sigma) p2_pdf = stats.norm.pdf(p2, p2_mu, p2_sigma) xmin = min(min(p1), min(p2)) xmax = max(max(p1), max(p2)) x = np.linspace(xmin, xmax, 1000) y = np.minimum(p2_pdf, p1_pdf) fig, ax = plt.subplots() ax.plot(p1, p1_pdf) ax.plot(p2, p2_pdf) ax.fill_between(x, y, color='red', alpha=0.3) plt.show()
错误填充效果

问题原因
原代码核心错误:p1_pdf基于x序列p1计算,p2_pdf基于x序列p2计算,两个数组对应的x坐标完全不匹配,直接对两个数组取np.minimum得到的结果,根本不是同一x坐标下两个分布pdf的较小值,自然无法正确定位重叠区域。
正确实现方案
统一使用覆盖两个分布全范围的同一条x序列,分别计算两个分布在该序列上的pdf值,再取同x位置两个pdf的最小值作为填充上边界,即可精准填充重叠区域,修正后代码如下:
import matplotlib.pyplot as plt import numpy as np import scipy.stats as stats p1_mu = 25 p2_mu = 50 p1_sigma = 25/3 p2_sigma = p1_sigma # 生成覆盖两个分布3σ范围的统一x轴序列 xmin = p1_mu - 3 * p1_sigma xmax = p2_mu + 3 * p2_sigma x = np.linspace(xmin, xmax, 1000) # 在统一x轴上计算两个分布的概率密度 p1_pdf = stats.norm.pdf(x, p1_mu, p1_sigma) p2_pdf = stats.norm.pdf(x, p2_mu, p2_sigma) # 取同x位置两个pdf的较小值,作为重叠区域的上边界 overlap_y = np.minimum(p1_pdf, p2_pdf) fig, ax = plt.subplots() ax.plot(x, p1_pdf) ax.plot(x, p2_pdf) ax.fill_between(x, overlap_y, color='red', alpha=0.3) plt.show()
运行代码后,填充区域会严格限制在两条概率密度曲线的交集范围内,不会出现原代码中错位填充的问题。
内容的提问来源于stack exchange,提问作者Vivek Joshy
相关产品推荐
相关产品推荐

