2012-09-02 31 views
2

我有图的下列组合:如何在两条曲线下面着色区域?

import pylab as pl 
import numpy as np 


def gauss2d(x,sigma): 
    return (1/np.sqrt(2*np.pi*sigma))*np.exp(-1/2*(x/sigma)**2) 

def markParameters(m,s,textsigma, textmean): 
    p1=gauss2d(s,s) 
    p2=gauss2d(0,s) 

    pl.annotate("", xy=(m-s, p1), xycoords='data', xytext=(m+s, p1), textcoords='data', arrowprops=dict(arrowstyle="<->", connectionstyle="arc3"),) 
    pl.text(m,p1,textsigma,horizontalalignment='center',verticalalignment='top') 
    pl.annotate("", xy=(m, p2*1.1), xycoords='data', xytext=(m, p2*1.1), textcoords='data', arrowprops=dict(arrowstyle="->", connectionstyle="arc3"),) 
    pl.text(m,p2*1.1,textmean,horizontalalignment='center',verticalalignment='top') # ,rotation=90 
    pl.plot(m,p2) 
    pl.plot(m,p2, marker="o", markeredgecolor="blue", markersize=5.0, linestyle=" ",color="blue") 


def plot_gauss2d(): 
    x = np.mgrid[100:135:100j] 

    m,s=123.24,3.56 
    pl.plot(x,gauss2d(x-m,s), 'b-') 
    markParameters(m,s, "$\sigma_{1}$","$\omega_{1}$") 

    m,s=120.15,4.62 
    pl.plot(x,gauss2d(x-m,s), 'b-') 
    markParameters(m,s, "$\sigma_{2}$","$\omega_{2}$") 


    m,s=109.67,3.85 
    pl.plot(x,gauss2d(x-m,s), 'b-') 
    markParameters(m,s,"$\sigma_{3}$","$\omega_{3}$") 

def main(): 
    plot_gauss2d() 

if __name__ == "__main__": 
    main() 

导致下面的图: example

现在我想有对颜色,其中两个函数重叠的空间。像这样的图片: enter image description here

作为奖励,我想在该空间的某处插入两个箭头,但不知何故无法完全管理它。

回答

2

这可能不是最完美的解决方案,但你可以得到与fill_between预期的效果,一旦你解决了十字路口:

import matplotlib.pyplot as pl 
import numpy as np 
from scipy.optimize import fsolve 


def gauss(x, mu, sig): 
    return 1/np.sqrt(2 * np.pi)/sig * np.exp(-((x - mu)/sig)**2/2.) 


def mark_parameters(m, s, textsigma, textmean): 
    p1 = gauss(m + s, m, s) 

    w = 0.0001 
    pl.arrow(m, p1, +s, 0, fc='b', ec='b', length_includes_head=True, 
      head_width=w*30, head_length=w*3000, width=w) 
    pl.arrow(m, p1, -s, 0, fc='b', ec='b', length_includes_head=True, 
      head_width=w*30, head_length=w*3000, width=w) 

    pl.text(m, p1*0.98, textsigma, horizontalalignment='center', 
      verticalalignment='top') 

    p2 = gauss(m, m, s) 
    pl.text(m, p2*1.05, textmean, horizontalalignment='center', 
      verticalalignment='top') 
    pl.plot(m, p2, marker="o", markeredgecolor="blue", 
      markersize=5.0, linestyle=" ", color="blue") 


def plot_gauss(): 
    x = np.arange(100, 135, 0.01) 

    pars = [(123.24, 3.56), (120.15, 4.62), (109.67, 3.85)] 
    ipcolor = {(0, 1): 'red', (1, 2): 'green'} 

    prev = None 
    for i, (m, s) in enumerate(pars): 
     pl.plot(x, gauss(x, m, s), 'b-') 
     j = i + 1 
     mark_parameters(m, s, "$2\sigma_{%d}$" % j, "$\omega_{%d}$" % j) 

     if prev: 
      ip, (mp, sp) = prev 

      # look for intersection 
      x0 = 0.5 * (mp + m) # initial guess for x 
      xi = fsolve(lambda x : gauss(x, mp, sp) - gauss(x, m, s), x0) 

      # fill between gauss and y = 0, divided at intersection xi 
      color = ipcolor[(ip, i)] if (ip, i) in ipcolor else 'none' 
      pl.fill_between(x, gauss(x, mp, sp), where=(x <= xi), 
          color=color) 
      pl.fill_between(x, gauss(x, m, s), where=(x > xi), 
          color=color) 

     prev = (i, (m, s)) 


def main(): 
    plot_gauss() 
    pl.show() 


if __name__ == "__main__": 
    main()