Оттенок / заливка между произвольной областью Matplotlib на основе осей, а не данных - PullRequest
2 голосов
/ 03 апреля 2020

Возможно ли заполнение между произвольными областями диаграммы не на основе нанесенных данных, а в диапазоне оси X?

На графике временных рядов ниже я закрашиваю область между 8 вечера и 8 утра, используя это вызов fill_between:

ax3.fill_between(d[0], 0, ax3.get_ylim()[1], where=fill, facecolor=face_color )

Где fill определяется на основе данных, записанных в течение этих часов:

fill = [False if dt.time(8,0,0) < t.time() < dt.time(20,0,0) else True for t in d[0]]

Это прекрасно работает для первых двух заштрихованных областей.

enter image description here

Проблема в том, что иногда записанные данные не будут присутствовать в течение этих часов, и поэтому заштрихованная область слишком мала и не представляет соответствующие часы ( см. 3-ю заштрихованную область на диаграмме)

Я понимаю, что мог бы сделать это, создав другой набор данных с соответствующим диапазоном значений x, а затем установив его как невидимый, но я хотел знать, есть ли другой способ.

1 Ответ

2 голосов
/ 04 апреля 2020

Вы можете создать массив из datetime объектов, которые охватывают тот же диапазон, что и ваши x данные, и использовать его для заполнения массива fill,

import numpy as np
# ...
fill = [False if dt.time(8, 0, 0) < t.time() < dt.time(20, 0, 0) else True for t in 
        np.arange(x[0], x[-1]+60, 60, dtype='datetime64').astype(dt.datetime)]

Полный пример:

import matplotlib.pyplot as plt
import datetime as dt
import numpy as np

plt.figure(figsize=(12,3))
x = np.arange('2020-04-03T00:00Z', '2020-04-05T00:30Z', np.random.randint(50, 70), 
              dtype='datetime64[m]')
x = np.delete(x, np.s_[4:10])
x = np.delete(x, np.s_[25:32])
y = np.sin(np.linspace(0, np.pi*2, len(x))*2 + np.random.random(len(x)) - 0.5)
plt.plot(x, y)

dx = np.arange(x[0], x[-1]+60, 60, dtype='datetime64[m]').astype(dt.datetime)
fill = [False if dt.time(8, 0, 0) < t.time() < dt.time(20, 0, 0) else True for t in dx]
plt.fill_between(dx, plt.ylim()[0], plt.ylim()[1], where=fill, fc='grey', alpha=0.2)

plt.tick_params(axis='x', rotation=90)
plt.subplots_adjust(bottom=0.3)
plt.show()

enter image description here

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