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