Вызов plt.xticks
только с одним параметром строк не является хорошим подходом. Первым параметром xticks
должен быть список чисел, мест на оси X, где вы хотите поставить галочку. Необязательным вторым параметром будет список строк, которые будут записаны на этих галочках.
В вашем случае у вас есть только строки для оси X. Внутренне это просто числа 0,1,2,...
. Это означает, что на текущем графике ширина всех шагов равна и составляет ровно одну позицию.
Одним из способов go далее является численное создание оси x, например, измерение в минутах. , Таким образом, ширина ваших шагов может быть пропорциональна длине интервала.
В этом случае вы можете рассчитывать тики за каждые 15 минут. И отметьте метки для каждого из этих тиков как часы и минуты (HH:MM
).
Вот код для этого. Я выбрал шрифт меньшего размера и повернул метки, чтобы они поместились на странице.
from matplotlib import pyplot as plt
fig = plt.figure(figsize=(17, 2))
ax = fig.add_subplot(111)
padded = [['21:20:24', '21:21:15', '51', '1'], ['21:27:55', '21:29:15', '80', '1'], ['21:38:16', '21:40:15', '119', '1'], ['22:13:44', '22:19:31', '347', '3'], ['22:24:42', '22:26:15', '93', '1'], ['22:47:29', '22:49:15', '106', '1']]
x = []
y = []
for line in padded:
# change x's from text to a number in minutes
x0, x1 = [int(h) * 60 + int(m) + int(s) / 60.0 for i in (0, 1) for h, m, s in [line[i].split(':')]]
x.append(x0)
y.append(int(line[2]))
x.append(x1)
y.append(int(line[2]))
ax.step(x, y, label="day_i")
plt.title("day")
plt.xlabel("Time")
plt.ylabel("Interval length (s)")
plt.legend()
ticks = []
labels = []
for i in range(0, 25):
for j in range(0, 60, 15):
labels.append(f"{i:02}:{j:02}")
ticks.append(i * 60 + j)
if i == 24: # make 24:00 the last tick
break
plt.xticks(ticks, labels, rotation=90, fontsize=8)
plt.tight_layout()
plt.show()
Можно создать код для создания тиков подробнее Pythoni c выглядит следующим образом.
ticks = range(0, 24*60+1, 15)
labels = [f"{m // 60:02}:{m % 60:02}" for m in ticks]
Преимущество заключается в том, что вы можете просто поменять галочки, и надписи все равно будут в порядке. Например:
ticks = range(0, 24*60+1, 60)
labels = [f"{m // 60:02}:{m % 60:02}" for m in ticks]
minor_ticks = range(0, 24*60+1, 15)
plt.xticks(ticks, labels, fontsize=10)
ax.xaxis.set_ticks(minor_ticks, minor=True)
Возможно, при создании массива y
вы могли бы установить второй y
в 0
, так как пошаговый график уже позаботился о рисовании шагов, а 0 быть полезным для промежуточных интервалов без данных. В этом случае вам нужно добавить where='post'
к графику step
(чтобы указать, что новый шаг действителен после x0). И вам нужно добавить еще 0 в начале и в конце дня (ax.step([0]+x+[24*60], [0]+y+[0], where='post', label=...)
).
Увеличение данных в вашем примере будет выглядеть так: