Как индексировать даты при рисовании прямоугольников - PullRequest
0 голосов
/ 22 мая 2018

Для анализа данных я хотел бы создать график с серым полосатым фоном.Серый или белый фон зависит от значения (1 или 0) в другом массиве.Рисунок выглядит следующим образом:

enter image description here

import matplotlib.patches as patches

idx = np.linspace(0, nr_burst, nr_burst)
x = total #length nr_burst 
y = tide #zeros and ones of length nr_burst

fig, ax = plt.subplots(1, figsize=(15,5))
ax.plot(idx, x)
rect_height = np.max(x)
rect_width = 1

for i, draw_rect in enumerate(y):
    if draw_rect:
        rect = patches.Rectangle(
            (i, 0),
            rect_width,
            rect_height,
            linewidth=1,
            edgecolor='lightgrey',
            facecolor='lightgrey',
            fill=True
        )
        ax.add_patch(rect)

plt.show();

Однако я бы хотел, чтобы ось X указывала даты вместо индекса данных,Когда я попытался заменить idx на date (объект datetime.datetime длиной nr_burst), он выдал ошибку: аргумент float () должен быть строкой или числом, а не datetime.datetime.

Thisбыл код:

import matplotlib.patches as patches

idx = dates #with length nr_burst as well
x = total #length nr_burst 
y = tide #zeros and ones of length nr_burst

fig, ax = plt.subplots(1, figsize=(15,5))
ax.plot(idx, x)
rect_height = np.max(x)
rect_width = 1

for i, draw_rect in enumerate(y):
    if draw_rect:
        rect = patches.Rectangle(
            (dates[i], 0),
            rect_width,
            rect_height,
            linewidth=1,
            edgecolor='lightgrey',
            facecolor='lightgrey',
            fill=True
        )
        ax.add_patch(rect)

plt.show();

Надеюсь, я достаточно ясно объясняю, чего хочу достичь.

1 Ответ

0 голосов
/ 22 мая 2018

Ваш код может быть исправлен путем преобразования dates в даты :

import matplotlib.dates as mdates
datenums = mdates.date2num(dates)

и последующего определения прямоугольников с использованием дат даты:

patches.Rectangle((datenums[i], 0),...)

Например,

import numpy as np
import matplotlib.patches as patches
import matplotlib.dates as mdates
import matplotlib.pyplot as plt

nr_burst = 50
dates = (np.array(['2000-01-01'], dtype='datetime64[D]') 
         + ((np.random.randint(1, 10, size=nr_burst).cumsum()).astype('<timedelta64[D]')))
idx = dates #with length nr_burst as well
x = np.random.random(nr_burst).cumsum() #length nr_burst 
y = np.random.randint(2, size=nr_burst) #zeros and ones of length nr_burst
datenums = mdates.date2num(dates)

fig, ax = plt.subplots(1, figsize=(15,5))
ax.plot(idx, x)
rect_height = np.max(x)
rect_width = 1

for i, draw_rect in enumerate(y):
    if draw_rect:
        rect = patches.Rectangle(
            (datenums[i], 0),
            rect_width,
            rect_height,
            linewidth=1,
            edgecolor='lightgrey',
            facecolor='lightgrey',
            fill=True
        )
        ax.add_patch(rect)

plt.show()

enter image description here

В качестве альтернативы, вы можете использовать ax.axvspan для создания выделенных областей :

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

nr_burst = 50
dates = (np.array(['2000-01-01'], dtype='datetime64[D]') 
         + ((np.random.randint(1, 10, size=nr_burst).cumsum()).astype('<timedelta64[D]')))
idx = dates #with length nr_burst as well
x = np.random.random(nr_burst).cumsum() #length nr_burst 
y = np.random.randint(2, size=nr_burst) #zeros and ones of length nr_burst
datenums = mdates.date2num(dates)

fig, ax = plt.subplots(1, figsize=(15,5))
ax.plot(idx, x)

for datenum, yi in zip(datenums, y):
    if yi:
        ax.axvspan(datenum, datenum+1, facecolor='red', alpha=0.5)

plt.show()

enter image description here

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