Предыстория: из большого DataFrame
я отфильтровала записи за year=2013
, month=June
, недели 3-9 числа (с понедельника по воскресенье). Затем я сгруппировал данные по day
, hour
и user_type
и повернул таблицу, чтобы получить DataFrame
, который выглядит так:
Day Hour Casual Registered Casual_percentage
0 3 0 14 19 42.42
1 3 1 8 8 50.00
2 3 2 1 3 25.00
3 3 3 2 1 66.67
4 3 4 1 3 25.00
5 3 5 1 17 5.56
. . . . . .
На каждый день у меня есть 24 часа, поэтому для дня 4 (вторник) данные начинаются так:
. . . . . .
21 3 21 32 88 26.67
22 3 22 26 64 28.89
23 3 23 23 30 43.40
24 4 0 10 11 47.62
25 4 1 1 5 16.67
26 4 2 1 1 50.00
. . . . . .
Как я могу построить переменные Casual
и Registered
на Hour
для каждой из 7 Day
s? Мне нужно будет создать 7 разных графиков и выровнять их по 1 фигуре?
Текущий код. Я чувствую, что я далеко. Я также пытался создать вторая ось x (для Days
), используя документация.
def make_patch_spines_invisible(ax):
ax.set_frame_on(True)
ax.patch.set_visible(False)
for sp in ax.spines.values():
sp.set_visible(False)
fig, ax1 = plt.subplots(figsize=(10, 5))
ax1.set(xlabel='Hours', ylabel='Total # of trips started')
ax1.plot(data.Hour, data.Casual, color='g')
ax1.plot(data.Hour, data.Registered, color='b')
"""This part is trying to create the 2nd x-axis (Days)"""
ax2 = ax1.twinx()
#offset the bottom spine
ax2.spines['bottom'].set_position(('axes', -.5))
make_patch_spines_invisible(ax2)
#show bottomm spine
ax2.spines['bottom'].set_visible(True)
ax2.set_xlabel("Days")
plt.show()
Предполагая, что ваши данные упорядочены по индексу (например, 0–24 — это день 3, 25–48 — это день 4 и т. д.), вы можете отображать значения индекса, а не часы в своем коде:
ax1.plot(data.index.values, df.Casual, color='g')
ax1.plot(data.index.values, df.Registered, color='b')
Это даст график, аналогичный тому, что вы ищете в качестве конечного продукта (обратите внимание, что я использовал поддельные данные):
Итак, да, вам нужно переформатировать ваши данные, как упоминалось в другом ответе. Работа с отдельными столбцами для часов, дней, месяцев и т. д. не является bueno, и вы должны объединить их в объект datetime.
Я думаю, это должно быть проще, если вы работаете с datetime
объектами, а не Day
, Hour
строками.
Таким образом, вы сможете использовать локаторы даты и средства форматирования
вместе с основные и второстепенные тики.
Даже если вы не упомянули об этом, я предполагаю, что вы можете использовать pandas
для работы с фреймами данных.
Я создал новый датафрейм, многократно скопировав предоставленные вами данные и вырезав некоторые из них (это не так важно).
Здесь я перестроил даты из предоставленной вами информации, но я предлагаю работать непосредственно с ними (я полагаю, что в исходном фрейме данных есть какое-то поле, похожее на дату).
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
df = pd.read_csv("mydataframe.csv")
df["timestamp"] = "2013-06-" + df["Day"].astype(str).str.zfill(2) + "-" + df["Hour"].astype(str).str.zfill(2)
df["timestamp"] = pd.to_datetime(df["timestamp"], format = "%Y-%m-%d-%H")
fig, ax1 = plt.subplots(figsize=(10, 5))
ax1.set(xlabel='', ylabel='Total # of trips started')
ax1.plot(df["timestamp"], df.Casual, color='g')
ax1.plot(df["timestamp"], df.Registered, color='b')
ax1.xaxis.set(
major_locator=mdates.DayLocator(),
major_formatter=mdates.DateFormatter("\n\n%A"),
minor_locator=mdates.HourLocator((0, 12)),
minor_formatter=mdates.DateFormatter("%H"),
)
plt.show()
Выход:
Да, DataFrame
(уже хранящий значения для 13 июня 3-9) имеет переменную datetime
s_datetime
, и я сделал: data = df.groupby([df['s_timedate'].dt.day, df['s_timedate'].dt.hour, df.user_type]).agg({'hubway_id':'count'})
чтобы получить количество за день и час. Но если я правильно понимаю, я должен получить счет, сохраняя переменную datetime со столбцами: date_time
, Casual
, Registered
?
@ Bn.F76 Да, вы должны сохранить переменную даты и времени. Чтобы добиться группировки по времени, вы также можете использовать панд resample
. Посмотрите, например, на этот вопрос stackoverflow.com/questions/49344899/…
Спасибо! И последнее, что означает mdates.DateFormatter("\n\n%A")
? Я знаю, что %H
получает час, %Y
год и т. д., но я не понимаю вашего выражения и хочу поиграть, поэтому я получаю тики за каждый час в 24-часовом окне.
@Bn.F76 в "\n\n%A"
, \n\n
просто помещает дни недели на две строки ниже часовых меток, а %A
получает «День недели как полное название региона». Посмотрите на strftime.org
К сожалению, в течение нескольких недель нет данных за определенные часы, поэтому индексный подход не является точным/надежным.