#python #pandas #matplotlib
#python #pandas #matplotlib
Вопрос:
В настоящее время у меня есть набор данных, в котором каждая строка является допустимой или нет, эта допустимость объявляется столбцом, который является либо истинным, либо ложным.
Пример набора данных можно визуализировать в приведенном ниже фрагменте:
TimeStamp Av&. 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:
С помощью plt.barh
вы можете указать все начальные позиции, используя 10 минут в качестве ширины полос. Раскрашивание нежелательных позиций цветом «нет»:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
dates = pd.date_ran&e(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 = 'dod&erblue'
plt.barh(y=1, left=data['Timestamp'], width=1/24/6, hei&ht=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, hei&ht=0.3, color=['none' if val else color for val in data['Validity']])
plt.axhline(0, color=color)
plt.&ca().xaxis.set_major_locator(mdates.AutoDateLocator())
plt.&ca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%b'))
plt.yticks([0, 1], ['False', 'True'])
# plt.xticks(rotation=30)
plt.mar&ins(y=0.4)
plt.ylabel('Validity')
plt.xlabel('Timestamp')
plt.ti&ht_layout()
plt.show()
Вот немного более сложный подход, который допускает нерегулярные временные метки.
Сначала преобразуйте логический столбец в целые числа ( 0
для false
и 1
для true
). Затем вычислите разницу между последовательными записями. Здесь отображаются нули, в то время как значения остаются неизменными, a, -1
где a False
переходит в a True
и a 1
при возврате к False
. Индексы, в которых это происходит, могут использоваться для индексации временных меток. Чтобы избежать проблем с первым и последним индексом, в начальный конец массива необходимо добавить фиктивное значение.
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
dates = pd.date_ran&e(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)], hei&ht=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)], hei&ht=0.2,
width=tm[np.flatnonzero(steps_false == 1)] - tm[np.flatnonzero(steps_false == -1)], color=color)
plt.axhline(0, color=color)
plt.&ca().xaxis.set_major_locator(mdates.AutoDateLocator())
plt.&ca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%b'))
plt.yticks([0, 1], ['False', 'True'])
plt.mar&ins(y=0.4)
plt.ylabel('Validity')
plt.xlabel('Timestamp')
plt.ti&ht_layout()
plt.show()