我经常需要在简洁的图中指出一些数据的分布,如下图所示。我通过绘制几个fill_between
区域来做到这一点,受到分布的分位数的限制。
ax.fill_between(x, quantile1, quantile2, alpha=0.2)
在for循环中,我通过计算分位数1和2(如图例所示)为0%到100%分位数,然后10%到90%等等,每个{{1}来制作这样的图。绘制在前一个"层"。
之上这是具有三层透明颜色和中间线(0.5)的输出:
但是,图例颜色不是我想要的颜色,因为它们(自然地)使用每个单独图层的颜色,而不考虑多个图层的组合效果。
fill_between
在图例命令中覆盖面部颜色值的最佳方法是什么?
我希望避免这样做,首先绘制0%到10%的透明度" 0.2"然后10%到30%的透明度" 0.4"等等,因为这将花费两倍的时间来计算并使代码更复杂。
答案 0 :(得分:1)
您可以使用代理艺术家在图例中放置与图中生成的叠加层完全相同的透明度
作为代理艺术家,您可以使用简单的矩形。但是,需要计算透明度,因为透明度为0.2
的两个对象将显示为具有透明度0.36
(而非0.4
!)的单个对象。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches
a = np.sort(np.random.rand(6,18), axis=0)
x = np.arange(len(a[0]))
def alpha(i, base=0.2):
l = lambda x: x+base-x*base
ar = [l(0)]
for j in range(i):
ar.append(l(ar[-1]))
return ar[-1]
fig, ax = plt.subplots(figsize=(4,2))
handles = []
labels=[]
for i in range(len(a)/2):
ax.fill_between(x, a[i, :], a[len(a)-1-i, :], color="blue", alpha=0.2)
handle = matplotlib.patches.Rectangle((0,0),1,1,color="blue", alpha=alpha(i, base=0.2))
handles.append(handle)
label = "quant {:.1f} to {:.1f}".format(float(i)/len(a)*100, 100-float(i)/len(a)*100)
labels.append(label)
plt.legend(handles=handles, labels=labels, framealpha=1)
plt.show()
<小时/> 人们必须决定这是否值得付出努力。没有透明度但具有相同结果的解决方案可以实现更短的时间:
import matplotlib.pyplot as plt
import numpy as np
a = np.sort(np.random.rand(6,18), axis=0)
x = np.arange(len(a[0]))
fig, ax = plt.subplots(figsize=(4,2))
for i in range(len(a)/2):
label = "quant {:.1f} to {:.1f}".format(float(i)/len(a)*100, 100-float(i)/len(a)*100)
c = plt.cm.Blues(0.2+.6*(float(i)/len(a)*2) )
ax.fill_between(x, a[i, :], a[len(a)-1-i, :], color=c, label=label)
plt.legend( framealpha=1)
plt.show()