Matplotlib Fill_between не работает с двумя кривыми и условием 'где' - PullRequest
1 голос
/ 27 февраля 2020

У меня есть следующий код:

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)

, который производит этот вывод: enter image description here

Теперь, что я действительно хочу получить (см. Где условие) - это заполненная область между осью x и pvlist (зеленая линия), НО ТОЛЬКО в тех областях, где кривая находится под tildelist (красная линия). Похоже, где условие не рассматривается. Более того, если я инвертирую условие (pvlist> tildelist), оно действительно работает! Но это не то, что я хочу получить.

Я также пытался преобразовать списки в numpy массивы, как предлагалось для подобных вопросов, но это не сработало.

Любая помощь приветствуется , Привет

1 Ответ

2 голосов
/ 27 февраля 2020

Из do c для fill_between:

where массив bool (длина N), необязательно, по умолчанию: нет

Определить, где исключить некоторые горизонтальные области из заполнения. Заполненные области определяются координатами x [где]

Так что здесь важны две вещи, во-первых, ваше сравнение списков просто возвращает единственное логическое значение:

print(pvlist < tildelist)
# True

Как вы предложили, один из вариантов - использовать numpy массивы:

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

. Для меня это работает и дает следующие графики: слева pvlist<tildelist и справа pvlist>tildelist:

fillbetween fillbetween

Во-вторых, where определяет, где исключить заполнение некоторых горизонтальных областей .

Если вы хотите:

заполненная область между осью x и pvlist (зеленая линия), НО ТОЛЬКО в областях, где кривая находится под tildelist (красная линия)

Вы не хотите, чтобы некоторые горизонтальные субрегионы должны быть исключены, но вы хотите исключить некоторые вертикальные субрегионы. Другими словами, вы хотите заполнить область между осью 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

Можно добавить интерполяцию, поскольку fill_between работает только по точкам, поэтому контуры не заполнены точно. Сначала линейно интерполируя две кривые, а затем вычисляя минимум, результат более точно следует кривым:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...