2017-02-20 420 views
2

我经常需要在简明图中指示一些数据的分布,如下图所示。我这样做是通过绘制几个fill_between区域,受分布分位数的限制。Matplotlib中相交透明图层的正确图例颜色

ax.fill_between(x, quantile1, quantile2, alpha=0.2) 

在for循环中,我通过计算位数1和2(由图例所指示的)的0%到100%分位数,然后用10%至90%等,每个作出这样重复fill_between绘制在先前的“图层”之上。

这里是用透明颜色的三个层中的输出与所述中线(0.5)沿着:
Three layers of transparent colors along with the median line (0.5)

然而,图例颜色不是我想他们是,因为它们(自然)使用每个单独图层的颜色,而不考虑几个图层的组合效果。

ax.legend([0.5]+[['0.0%', '100.0%'], ['10.0%', '90.0%'], ['30.0%', '70.0%']]) 

覆盖图例命令中的脸部颜色值的最佳方法是什么?

我想避免这样做,首先用透明度“0.2”绘制0%到10%,然后用透明度“0.4”绘制10%到30%等等,因为这需要花费两倍的时间计算并将使代码更复杂。

回答

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() 

enter image description here


一个人来决定,如果这是真的值得去努力。缺乏透明度,但与非常相同的结果的解决方案,可以实现更短:

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() 

enter image description here

+0

非常感谢你。没有透明度的解决方案非常好! – GunnarGeir

+0

顺便说一下,第一种方法不需要alpha函数定义。相反,for循环可以使用更新alpha值。 alpha = 0.2 if i == 0 else alpha *(1-0.2)+0.2 句柄线将使用alpha = alpha。 – GunnarGeir