首先,我寻找了一个可以处理颜色的函数,并遇到了matplotlib的fill_between
方法。然后,我使用np.linspace
定义了三个x向量,并使用了for循环,使用fill_between
来阴影区域。然后,我意识到fill_between
将“连接”两个区域,即使我希望中间部分不加阴影(这适用于“高于和低于平均值”和“高于和低于平均值”)。因此,该方法不起作用。
然后,我在where
中遇到了fill_between
关键字参数,并提出了一个使用逻辑运算符定义三个区域的解决方案。此方法有效,但我对它并不满意,并强烈感到必须找到一种更有效的方法来解决此问题?
这是我的代码:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
plotdata = {"mean": 50,"sd": 10}
# plot normal distribution
x_normdist = np.linspace(plotdata["mean"] - 3 * plotdata["sd"], plotdata["mean"] + 3 * plotdata["sd"],1000)
y = norm.pdf(x_normdist,plotdata["mean"],plotdata["sd"])
plt.plot(x_normdist,y)
# create logical lists
average = (x_normdist >= (plotdata["mean"] - 1 * plotdata["sd"])) & (x_normdist <= (plotdata["mean"] + 1 * plotdata["sd"]))
above_and_below_average = (x_normdist >= (plotdata["mean"] - 2 * plotdata["sd"])) & (x_normdist < (plotdata["mean"] - 1 * plotdata["sd"])) | (x_normdist > (plotdata["mean"] + 1 * plotdata["sd"])) & (x_normdist <= (plotdata["mean"] + 2 * plotdata["sd"]))
far_above_and_belowe_average = (x_normdist >= (plotdata["mean"] - 3 * plotdata["sd"])) & (x_normdist < (plotdata["mean"] - 2 * plotdata["sd"])) | (x_normdist > (plotdata["mean"] + 2 * plotdata["sd"])) & (x_normdist <= (plotdata["mean"] + 3 * plotdata["sd"]))
# bind lists
regions = [average,above_and_below_average,far_above_and_belowe_average]
# set alpha values
alpha_values = [0.75,0.5,0.25]
# plot regions with corresponding alpha values
for idx,region in enumerate(regions):
y = norm.pdf(x_normdist, plotdata["mean"], plotdata["sd"])
plt.fill_between(x_normdist, y,color="C0",alpha=alpha_values[idx],where=regions[idx])
plt.show()
答案 0 :(得分:0)
我@Bazingaa同意你的解决方案可能不够好,易于阅读。如果您想树荫许多不同的时间间隔,它会得到麻烦,虽然。你可以优化该过程像下面,但是代码是可读的要少得多。
from scipy.stats import norm
m=50.
sd=10.
fig, ax = plt.subplots()
x = np.linspace(m-3*sd,m+3*sd,1000)
y = norm.pdf(x,m,sd)
ax.plot(x,y,c='C0')
cutoffs = [0,0.25,0.6,1.2,3] # expressed in sd
colors = ['C0','C1','C2','C3']
alphas = [1.00,0.75,0.50,0.25]
where_x = np.zeros(len(x))
for cut in cutoffs:
where_x+=np.where(np.abs(x-m)>cut*sd,1,0)
for cond,c,a in zip(range(1,len(cutoffs)),colors,alphas):
ax.fill_between(x,y,color=c,alpha=a,where=(where_x==cond))