使用时间序列的百分位数在Python的matplotlib中设置颜色渐变

时间:2018-10-30 19:13:55

标签: python matplotlib

我有一个时间序列,在一年数组大小的过程中(365、10000),每天将有超过10,000个变量的每日值。因为我将拥有大量数据(许多时间序列包含许多变量),所以我希望仅保存百分位数(0、10、20,...,90、100),并在以后的绘图中使用它们来设置颜色渐变显示值的密度(显然在中值处最暗,在最小和最大值处最亮)。这样做的目的是避免在保存的模拟输出中文件过大,因为我将要处理数百万个输出。如果可以使用,这将大大减少文件大小。

我能够计算出样本数据集的百分位数(现在仅使用50个值)并按照附图进行绘制(使用大小为365,11的数组)进行绘制。我将如何使用此信息来建立一个显示颜色渐变(或值密度)的图?这可能吗?还是有其他解决方法?我正在使用matplotlib ...

 import numpy as np
 import matplotlib.pyplot as plt

 SampleData=(375-367)*np.random.random_sample((365, 50))+367
 SDist=np.zeros((365,11))
 for i in range(11):
     for t in range(365):
         SDist[t,i]=np.percentile(SampleData[t,:],i*10)

 fig, (ax1) = plt.subplots(nrows=1, ncols=1, sharex=True, figsize=(8,4))
 ax1.plot(np.arange(0,365,1), SDist)
 ax1.set_title("SampleData", fontsize=15)
 ax1.tick_params(labelsize=11.5)
 ax1.set_xlabel('Day', fontsize=14)
 ax1.set_ylabel('SampleData', fontsize=14)
 fig.tight_layout()

Sample Data showing Percentile Lines

编辑

这是我要做什么的一个很好的例子(尽管显然,它与示例数据看起来会有所不同)-我认为它与粉丝图表相似:

Percentiles used to define colour gradients

2 个答案:

答案 0 :(得分:0)

您可以使用matplotlib cm对象获取颜色图,并根据值手动计算要绘制的颜色。下面的示例根据线索引(0-11)计算要绘制的颜色。但是,只要您分别绘制它们并调用正确的颜色值,就可以根据任何内容(例如用于计算百分位数的观察值的数量)计算颜色。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

n = 11 # change this value for the number of iterations/percentiles
colormap = cm.Blues # change this for the colormap of choice
percentiles = np.linspace(0,100,n)

SampleData=(375-367)*np.random.random_sample((365, 50))+367
SDist=np.zeros((365,n))
for i in range(n):
    for t in range(365):
      SDist[t,i]=np.percentile(SampleData[t,:],percentiles[i])

half = int((n-1)/2)

fig, (ax1) = plt.subplots(nrows=1, ncols=1, sharex=True, figsize=(8,4))
ax1.plot(np.arange(0,365,1), SDist[:,half],color='k')
for i in range(half):
    ax1.fill_between(np.arange(0,365,1), SDist[:,i],SDist[:,-(i+1)],color=colormap(i/half))

ax1.set_title("SampleData", fontsize=15)
ax1.tick_params(labelsize=11.5)
ax1.set_xlabel('Day', fontsize=14)
ax1.set_ylabel('SampleData', fontsize=14)
fig.tight_layout()

结果应如下所示:

答案 1 :(得分:0)

fill_between最终解决了问题:

 import numpy as np
 import matplotlib.pyplot as plt

 SampleData=(375-367)*np.random.random_sample((365, 50))+367
 SDist=np.zeros((365,11))
 for i in range(11):
     for t in range(365):
         SDist[t,i]=np.percentile(SampleData[t,:],i*10)
 x=np.arange(0,365,1)

 fig, (ax1) = plt.subplots(nrows=1, ncols=1, sharex=True, figsize=(8,4))
 ax1.set_color_cycle(['red'])
 ax1.plot(x, SDist[:,5])
 for i in range(6):
     alph=0.05+(i/10.)
     ax1.fill_between(x, SDist[:,0+i], SDist[:,10-i], color="red", alpha=alph)
 ax1.set_title("SampleData", fontsize=15)
 ax1.tick_params(labelsize=11.5)
 ax1.set_xlabel('Day', fontsize=14)
 ax1.set_ylabel('SampleData', fontsize=14)
 fig.tight_layout()

Percentiles time series using fill between