问题
I have the following combinations of graphs:
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()
resulting in the following graph:
Now what i would like to have is to color the space where the two functions overlap. Like in this picture:
As a bonus I would like to insert two arrows somewhere in that space, but somehow cannot quite manage it.
回答1:
This may not be the most elegant solution, but you can get the desired effect with fill_between once you solve for the intersections:
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()
来源:https://stackoverflow.com/questions/12235668/how-do-i-color-the-area-below-the-two-curves