Время прорисовки в Python с Matplotlib
У меня есть массив временных меток в формате (ЧЧ: ММ: СС.мммммм) и другой массив чисел с плавающей запятой, каждое из которых соответствует значению в массиве временных меток.
Можно ли изобразить время на оси x и числа на оси y с помощью Matplotlib?
Я пытался, но почему-то принимал только массивы поплавков. Как я могу получить это, чтобы подготовить время? Нужно ли каким-либо образом изменять формат?
5 ответов
Сначала вы должны конвертировать ваши метки времени в Python datetime
объекты (использование datetime.strptime
). Тогда используйте date2num
конвертировать даты в формат matplotlib.
График даты и значения, используя plot_date
:
dates = matplotlib.dates.date2num(list_of_datetimes)
matplotlib.pyplot.plot_date(dates, values)
Вы также можете построить временные метки и пары значений, используя pyplot.plot (после анализа их по их строковому представлению). (Протестировано с версиями matplotlib 1.2.0 и 1.3.1.)
Пример:
import datetime
import random
import matplotlib.pyplot as plt
# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]
# plot
plt.plot(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()
plt.show()
Результирующее изображение:
Вот то же самое, что и график рассеяния:
import datetime
import random
import matplotlib.pyplot as plt
# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]
# plot
plt.scatter(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()
plt.show()
Создает изображение, похожее на это:
Спустя 7 лет этот код помог мне. Однако, мои времена все еще не показывались правильно.
Используя Matplotlib 2.0.0, мне пришлось добавить следующий фрагмент кода из раздела "Редактирование форматирования даты для меток оси x в matplotlib " Пола Х.
import matplotlib.dates as mdates
myFmt = mdates.DateFormatter('%d')
ax.xaxis.set_major_formatter(myFmt)
Я изменил формат на (%H:%M) и время отображается правильно.
Все благодаря сообществу.
У меня были проблемы с этим, используя версию Matplotlib: 2.0.2. Запустив пример сверху, я получил набор пузырьков по центру.
Я "исправил" проблему, добавив еще одну строку:
plt.plot([],[])
Весь фрагмент кода становится:
import datetime
import random
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# make up some data
x = [datetime.datetime.now() + datetime.timedelta(minutes=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]
# plot
plt.plot([],[])
plt.scatter(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()
myFmt = mdates.DateFormatter('%H:%M')
plt.gca().xaxis.set_major_formatter(myFmt)
plt.show()
plt.close()
Это создает изображение с пузырьками, распределенными по желанию.
Кадры данных Pandas еще не упоминались. Я хотел показать, как они решили мою проблему с датой и временем. У меня есть дата и время до миллисекунды
2021-04-01 16:05:37
. Я извлекаю пропускную способность linux/haproxy из /proc, поэтому я могу форматировать ее так, как мне нравится. Это удобно для ввода данных в анимацию живого графика.
Вот посмотрите на csv. (Игнорируйте столбец пакетов в секунду, который я использую на другом графике)
head -2 ~/data
date,mbps,pps
2021-04-01 16:05:37,113,9342.00
...
Используя
print(dataframe.dtype)
Я вижу, как данные были прочитаны в:
(base) ➜ graphs ./throughput.py
date object
mbps int64
pps float64
dtype: object
Pandas извлекает строку даты как «объект», который представляет собой просто тип char. Используя это как есть в сценарии:
import matplotlib.pyplot as plt
import pandas as pd
dataframe = pd.read_csv("~/data")
dates = dataframe["date"]
mbps = dataframe["mbps"]
plt.plot(dates, mbps, label="mbps")
plt.title("throughput")
plt.xlabel("time")
plt.ylabel("mbps")
plt.legend()
plt.xticks(rotation=45)
plt.show()
Matplotlib отображает все миллисекундные данные. я добавил
plt.xticks(rotation=45)
наклонить даты, но это не то, что я хочу. Я могу преобразовать дату «объект» в datetime64[ns]. Какой matplotlib умеет отображать.
dataframe["date"] = pd.to_datetime(dataframe["date"])
На этот раз моя дата типа
datetime64[ns]
(base) ➜ graphs ./throughput.py
date datetime64[ns]
mbps int64
pps float64
dtype: object
Тот же скрипт с разницей в 1 строку.
#!/usr/bin/env python
import matplotlib.pyplot as plt
import pandas as pd
dataframe = pd.read_csv("~/data")
# convert object to datetime64[ns]
dataframe["date"] = pd.to_datetime(dataframe["date"])
dates = dataframe["date"]
mbps = dataframe["mbps"]
plt.plot(dates, mbps, label="mbps")
plt.title("throughput")
plt.xlabel("time")
plt.ylabel("mbps")
plt.legend()
plt.xticks(rotation=45)
plt.show()
Это может быть не идеально для вашего варианта использования, но может помочь кому-то другому.