简体   繁体   English

Matplotlib Fill_between 不适用于两条曲线和“where”条件

[英]Matplotlib Fill_between not working with two curves and 'where' condition

I have the following code:我有以下代码:

import matplotlib.pyplot as plt

tildelist = [0.38878, 0.9275000000000001, 1.0493000000000001, 0.7799400000000001, 0.21630000000000005, 0.21630000000000005, 0.9074800000000002, 2.26002, 1.0837400000000001, 0.21630000000000005, 0.21630000000000005, 0.6433, 0.9429000000000001, 0.27622, 0.23996000000000003, 0.6216000000000002, 0.68894, 0.34230000000000005, 0.21630000000000005, 0.47656000000000004, 0.66556, 1.0437, 0.3661, 0.3346, 0.5712, 0.8986600000000002, 0.74746, 0.31094, 0.5712, 0.5661600000000001, 1.3006000000000002, 0.7340199999999999, 0.0, 0.0, 2.5052098332176604, 5.061356833449, 0.0, 0.0, 0.0, 0.0, 1.64234, 1.4148400000000003, 0.9455600000000002, 0.8230599999999999, 1.5153600000000003, 0.5336799999999999, 0.5082, 0.57232, 1.12322, 1.4065800000000002, 0.5368999999999999, 0.21630000000000005, 0.3465000000000001, 0.8829800000000001, 1.8379200000000002, 1.7056200000000001, 1.05252, 1.2306, 0.99176, 1.46076, 1.4128800000000001, 0.8652, 0.9966599999999999, 1.51438, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.6159, 3.1127600000000006, 2.7106800000000004, 2.6951400000000003, 4.0, 3.157, 2.1578199999999996, 1.9651800000000001, 1.06834, 1.69694, 1.2080600000000004, 0.8575000000000002]
pvlist = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0024485703275, 0.014189322872999998, 0.017274831464, 0.032399218874, 0.0437174946395, 0.054832859515499995, 0.08097311923249999, 0.14823322805499997, 0.183033049771, 0.3825400623385, 0.40805960146049997, 0.406044572373, 0.4546157846779999, 0.62414554279, 0.8040121546764999, 0.8566804419469998, 0.6471686383579999, 0.8845809490925, 0.883082102771, 0.43601875181149996, 1.0613568334489998, 1.1202136575354997, 1.1654046590229998, 1.2553348183145, 1.1136954158, 1.2222314657959998, 0.9697016623525, 1.2105366156069997, 1.3544616657385002, 0.5278753574214999, 1.353652237894, 1.4534492240674999, 0.6305305066884999, 0.9014175082879999, 0.5823572566129999, 1.0245447414455, 0.7280179826699998, 1.3126664895629998, 1.4048295308685, 1.4523198122069998, 1.2656314751189999, 1.2292708477774998, 1.143669808523, 1.1794532539404998, 0.9664060134575, 0.5818133189604999, 0.4612700229225, 0.8277498967979998, 0.7675148025655, 0.748532423232, 0.7318194628745, 0.5013466543799999, 0.39813316088149997, 0.23136454722699998, 0.1346367369215, 0.17184841006849996, 0.2261439741605, 0.377514939593, 0.302599843469, 0.107099320042, 0.09699960205649999, 0.08806879891699998, 0.045631237310999995, 0.025037315616499998, 0.009905696702, 0.007973754937499999, 0.003431330859, 0.001140702563, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
fixed_time_list = range(96)

resultimg, result = plt.subplots(figsize=(20, 10))
images, = result.plot(tildelist, linestyle='-', color='red')
images, = result.plot(pvlist, linestyle='-', color='green')

result.fill_between(fixed_time_list, pvlist, 0, where=pvlist<tildelist, facecolor='green', alpha=0.5)

plt.ylabel('Energy value (kW)')
plt.xlabel('Time instant')
plt.locator_params(axis='x', nbins=96)
plt.grid(True)
resultimg = plt.savefig('stackoverflow_example.png', dpi=200) 

plt.close(resultimg)

That produces this output:产生这个输出: 在此处输入图片说明

Now, what I actually want to obtain (see the where condition) is the area between the x axis and pvlist (the green line) filled, BUT ONLY in the areas where the curve is under tildelist (the red line).现在,我真正想要获得的(参见 where 条件)是 x 轴和 pvlist(绿线)之间的区域填充,但仅在曲线位于波浪线列表(红线)下方的区域中。 It seems like the where condition is not being considered.似乎没有考虑 where 条件。 Moreover, if I invert the condition (pvlist>tildelist), it actually works!此外,如果我反转条件(pvlist>tildelist),它确实有效! But that's not what I want to obtain.但这不是我想要的。

I also tried to convert the lists into numpy arrays, as suggested to similar questions, but it did not work.我还尝试按照类似问题的建议将列表转换为 numpy 数组,但没有奏效。

Any help is appreciated.任何帮助表示赞赏。 Regards问候

From the doc for fill_between :来自fill_between文档

where array of bool (length N), optional, default: None where bool 数组(长度 N),可选,默认值:无

Define where to exclude some horizontal regions from being filled.定义从填充中排除某些水平区域的位置。 The filled regions are defined by the coordinates x[where]填充区域由坐标 x[where] 定义

So two things are important here, first your comparison of the lists just returns a single boolean value:所以这里有两件事很重要,首先你的列表比较只返回一个布尔值:

print(pvlist < tildelist)
# True

As you suggested one option is to use numpy arrays:正如您所建议的,一种选择是使用numpy数组:

tildelist = np.array(tildelist)
pvlist = np.array(pvlist)
print(pvlist < tildelist)
# [ True  ... True False False False  True ... True False False True ...]

For me this works and produces the following plots, left pvlist<tildelist and right pvlist>tildelist :对我来说,这有效并产生以下图,左pvlist<tildelist和右pvlist>tildelist

fillbetweenfillbetween

The second thing is that where defines where to exclude some horizontal regions from being filled .第二件事是where定义了从哪里排除一些水平区域被填充

If you want:如果你想:

the area between the x axis and pvlist (the green line) filled, BUT ONLY in the areas where the curve is under tildelist (the red line) x 轴和 pvlist(绿线)之间的区域已填充,但仅在曲线位于波浪线列表(红线)下方的区域中

You don't want some horizontal sub regions to be excluded but rather you want to exclude some vertical sub regions.您不希望排除某些水平子区域,而是希望排除某些垂直子区域。 In other words you want to fill the area between the x axis and a new array which is defined as the minimum of the two curves:换句话说,您要填充 x 轴和定义为两条曲线最小值的新数组之间的区域:

pvlist_min = np.min(np.vstack([tildelist, pvlist]), axis=0)
result.fill_between(fixed_time_list, pvlist_min, 0, facecolor='green', alpha=0.5)

fillbetween

EDIT编辑

One could add interpolation, because fill_between works only point wise so the contours are not filled exactly.可以添加插值,因为fill_between仅适用于点,因此轮廓未完全填充。 By first interpolating the two curves linearly and then calculating the minimum the result follows the curves more closely:首先对两条曲线进行线性插值,然后计算最小值,结果更接近于曲线:

def get_x_substeps(x, n_substeps):
    x_steps = np.diff(x, axis=-1) / n_substeps
    delta = np.arange(n_substeps) * x_steps[..., np.newaxis]
    x_ss = (x[:-1, np.newaxis] + delta).flatten()
    x_ss = np.hstack([x_ss, x[-1]])
    return x_ss

n_substeps = 10
tildelist = get_x_substeps(x=tildelist, n_substeps=n_substeps)
pvlist = get_x_substeps(x=pvlist, n_substeps=n_substeps)
fixed_time_list = get_x_substeps(x=fixed_time_list, n_substeps=n_substeps)

pvlist_min = np.min(np.vstack([tildelist, pvlist]), axis=0)

result.fill_between(fixed_time_list, pvlist_min, 0, facecolor='green', alpha=0.5)

fillbetween

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM