Горизонтальный график для категорий с течением времени - PullRequest
2 голосов
/ 07 августа 2020
• 1000 :
                TimeStamp  Avg. Values  ... Validity
0     2015-02-14 20:30:00      5.1736  ...     False  
1     2015-02-14 20:40:00      16.6266  ...    True   
2     2015-02-14 20:50:00      12.7667  ...    True   
3     2015-02-14 21:00:00      11.6077  ...    False   
4     2015-02-14 21:10:00       19.6851  ...   True   
                  ...          ...  ...         ...    
1000 2015-06-12 23:30:00       1.699  ...      True  
1001 2015-06-12 23:40:00       2.2468  ...     False  
1002 2015-06-12 23:50:00       3.1147  ...     False  
1003 2015-06-13 00:00:00       6.141  ...      True  
1004 2015-06-13 00:10:00       3.792  ...      True  

Моя цель - построить график достоверности, как график Ганта, с течением времени с учетом достоверности столбца. Идея состоит в том, чтобы генерировать горизонтальные полосы, указывающие категорию данных с течением времени. Пример, который я придумал и не отражает приведенные выше данные, но показывает, чего я хочу достичь:

введите описание изображения здесь

Большинство горизонтальных гистограмм, которые я видел до сих пор, отображают только объем данных для каждой категории. Итак, можно ли каким-то образом изобразить его как график Ганта, показывая категории во времени?

1 Ответ

1 голос
/ 07 августа 2020

С помощью plt.barh вы можете указать все начальные позиции, используя 10 минут в качестве ширины полос. Раскрашивание нежелательных позиций цветом 'none':

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

dates = pd.date_range(start='2020-02-14 20:30', end='2020-02-24', freq='10min')
data = pd.DataFrame({'Timestamp': dates,
                     'Validity': (np.round(np.random.uniform(0, .02, len(dates)).cumsum()) % 2).astype(bool)})
color = 'dodgerblue'
plt.barh(y=1, left=data['Timestamp'], width=1/24/6, height=0.3,
         color=['none' if not val else color for val in data['Validity']])
plt.axhline(1, color=color)
plt.barh(y=0, left=data['Timestamp'], width=1/24/6, height=0.3, color=['none' if val else color for val in data['Validity']])
plt.axhline(0, color=color)

plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator())
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%b'))
plt.yticks([0, 1], ['False', 'True'])
# plt.xticks(rotation=30)
plt.margins(y=0.4)
plt.ylabel('Validity')
plt.xlabel('Timestamp')
plt.tight_layout()
plt.show()

example plot

Here is a slightly more involved approach, that permits irregular timestamps.

First convert the boolean column to integers (0 for false and 1 for true). Then calculate the difference between successive entries. This shows zeros while the values stay the same, a -1 where a False flips to a True and a +1 when flipping back to False. The indices where this happens can be used to index the timestamps. To avoid problems with the first and last index, a dummy value needs to be appended at the start end of the array.

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


dates = pd.date_range(start='2020-02-14 20:30', end='2020-02-24', freq='10min')
data = pd.DataFrame({'Timestamp': dates,
                     'Validity': (np.round((np.random.uniform(0, .02, len(dates))).cumsum()) % 2).astype(bool)})

tm = data['Timestamp'].to_numpy()
tm = np.append(tm, tm[-1])

color = 'navy'
steps_true = np.diff(np.concatenate([[False], data['Validity'], [False]]).astype(int))
plt.barh(y=1, left=tm[np.flatnonzero(steps_true == 1)], height=0.2,
         width=tm[np.flatnonzero(steps_true == -1)] - tm[np.flatnonzero(steps_true == 1)], color=color)
plt.axhline(1, color=color)
steps_false = np.diff(np.concatenate([[True], data['Validity'], [True]]).astype(int))
plt.barh(y=0, left=tm[np.flatnonzero(steps_false == -1)], height=0.2,
         width=tm[np.flatnonzero(steps_false == 1)] - tm[np.flatnonzero(steps_false == -1)], color=color)
plt.axhline(0, color=color)

plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator())
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%b'))
plt.yticks([0, 1], ['False', 'True'])
plt.margins(y=0.4)
plt.ylabel('Validity')
plt.xlabel('Timestamp')
plt.tight_layout()
plt.show()

второй сюжет

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