英文:
How to plot daily data against a 24 hour axis (00:00 - 23:59:59) while keeping the order of the custom sort of the time?
问题
由于您只需要翻译代码部分,以下是您提供的代码的翻译:
感谢 @Trenton McKinney,我知道如何在24小时坐标轴(00:00 - 23:59:59)上绘制每日数据[在这个问题中][1]。在以下数据集中,当我应用自定义排序**(custom_date_sorter函数)**时,图表不会按照custom_date_sorter函数中的顺序排列x轴。我希望x轴从12:00:00开始,结束于11:59:59。
import random
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.ticker as tkr
from datetime import time as dtime
random.seed(0)
df = pd.DataFrame({'DATE_TIME': pd.date_range('2022-11-01', '2022-11-06 23:00:00', freq='20min'),
'ID': [random.randrange(1, 3) for n in range(430)]})
df['VALUE1'] = [random.uniform(110, 160) for n in range(430)]
df['VALUE2'] = [random.uniform(50, 80) for n in range(430)]
df['INSPECTION'] = df['DATE_TIME'].dt.day
# df['INSPECTION'] = df['INSPECTION'].replace(6, 1)
# df['INSPECTION'] = df['INSPECTION'].replace(3, 1)
df['MODE'] = np.select([df['INSPECTION'] == 1, df['INSPECTION'].isin([2, 3])], ['A', 'B'], 'C')
df['TIME'] = df['DATE_TIME'].dt.time
df['TIME'] = df['TIME'].astype('str')
df['TIMEINTERVAL'] = df.DATE_TIME.diff().astype('timedelta64[m]')
df['TIMEINTERVAL'] = df['TIMEINTERVAL'].fillna(0)
def to_day_period(s):
bins = ['0', '06:00:00', '13:00:00', '18:00:00', '23:00:00', '24:00:00']
labels = ['Nighttime', 'Daytime', 'Daytime', 'Nighttime', 'Nighttime']
return pd.cut(
pd.to_timedelta(s),
bins=list(map(pd.Timedelta, bins)),
labels=labels, right=False, ordered=False
)
df['TIME_OF_DAY'] = to_day_period(df['TIME'])
# ++++++++++++++++++++++++++++++++ sns plot ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
df = df[(df['ID'] == 1) & (df['INSPECTION'].isin([1, 2, 3]))]
# +++++++++++++ CUSTOM SORTING +++++++++++++
def custom_date_sorter(s):
s = pd.to_datetime(s)
return np.argsort(np.lexsort(展开收缩))
df = df.sort_values(by='DATE_TIME', key=custom_date_sorter)
# +++++++++++++ ++++++++++++ +++++++++++++
sns.set_style('darkgrid')
sns.set(rc={'figure.figsize':(14,8)})
# 添加一个列来存储总秒数
df['total_seconds'] = df.DATE_TIME.apply(
lambda row: (row - row.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds())
# 遍历每个ID
for id_ in sorted(df.ID.unique()):
# 选择给定id_的数据
data = df[df.ID.eq(id_)]
# 创建一个图形
fig = plt.figure(figsize=(10, 6)
# 绘制数据
ax = sns.lineplot(data=data, x='total_seconds', y='VALUE1', hue='INSPECTION', palette='viridis', legend='full')
# 设置标题和标签
ax.set(title=f'ID: {id_}', xlabel='TIME', ylabel='VALUE1')
# 移动图例
sns.move_legend(ax, bbox_to_anchor=(1.0, 0.5), loc='center left', frameon=False)
# 限制x轴范围为一天的秒数
ax.set_xlim(0, 24 * 3600)
# 为一天中的每个小时创建标签,并添加一个额外的位置以匹配最后的刻度位置
hours = [dtime(i).strftime('%H:%M') for i in range(24)] + ['']
# 在每个小时创建xticks
ax.xaxis.set_major_locator(tkr.MultipleLocator(3600))
# 设置刻度和相应的标签;剪切掉多余的起始和结束刻度以匹配标签
ax.set_xticks(ticks=ax.get_xticks()[1:-1], labels=hours, rotation=90)
# 移除轴线
ax.spines[['top', 'right']].set_visible(False)
plt.show()
我如何在绘制每日数据对抗24小时轴时实现自定义排序,使x轴从12:00:00开始,结束于11:59:59。请注意,数据应正确反映,即不同时移动数据的时间不会有帮助。
<details>
<summary>英文:</summary>
Thanks to @Trenton McKinney, I know how to how to plot daily data against a 24 hour axis (00:00 - 23:59:59) [in this question][1]. In the following dataset, when I apply the custom sort **( custom_date_sorter function )**, the plot does not order the x-axis as in custom_date_sorter function. I want the x-axis o start at 12:00:00 to 00:00:00 and end at 11:59:59. :
```python
import random
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.ticker as tkr
from datetime import time as dtime
random.seed(0)
df = pd.DataFrame({'DATE_TIME': pd.date_range('2022-11-01', '2022-11-06 23:00:00', freq='20min'),
'ID': [random.randrange(1, 3) for n in range(430)]})
df['VALUE1'] = [random.uniform(110, 160) for n in range(430)]
df['VALUE2'] = [random.uniform(50, 80) for n in range(430)]
df['INSPECTION'] = df['DATE_TIME'].dt.day
# df['INSPECTION'] = df['INSPECTION'].replace(6, 1)
# df['INSPECTION'] = df['INSPECTION'].replace(3, 1)
df['MODE'] = np.select([df['INSPECTION'] == 1, df['INSPECTION'].isin([2, 3])], ['A', 'B'], 'C')
df['TIME'] = df['DATE_TIME'].dt.time
df['TIME'] = df['TIME'].astype('str')
df['TIMEINTERVAL'] = df.DATE_TIME.diff().astype('timedelta64[m]')
df['TIMEINTERVAL'] = df['TIMEINTERVAL'].fillna(0)
def to_day_period(s):
bins = ['0', '06:00:00', '13:00:00', '18:00:00', '23:00:00', '24:00:00']
labels = ['Nighttime', 'Daytime', 'Daytime', 'Nighttime', 'Nighttime']
return pd.cut(
pd.to_timedelta(s),
bins=list(map(pd.Timedelta, bins)),
labels=labels, right=False, ordered=False
)
df['TIME_OF_DAY'] = to_day_period(df['TIME'])
# ++++++++++++++++++++++++++++++++ sns plot ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
df = df[(df['ID'] == 1) & (df['INSPECTION'].isin([1, 2, 3]))]
# +++++++++++++ CUSTOM SORTING +++++++++++++
def custom_date_sorter(s):
s = pd.to_datetime(s)
return np.argsort(np.lexsort(展开收缩))
df = df.sort_values(by='DATE_TIME', key=custom_date_sorter)
# +++++++++++++ ++++++++++++ +++++++++++++
sns.set_style('darkgrid')
sns.set(rc={'figure.figsize':(14,8)})
# add a column for total seconds
df['total_seconds'] = df.DATE_TIME.apply(
lambda row: (row - row.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds())
# iterate through each ID
for id_ in sorted(df.ID.unique()):
# select the data for the given id_
data = df[df.ID.eq(id_)]
# create a figure
fig = plt.figure(figsize=(10, 6))
# plot the data
ax = sns.lineplot(data=data, x='total_seconds', y='VALUE1', hue='INSPECTION', palette='viridis', legend='full')
# set the title and labels
ax.set(title=f'ID: {id_}', xlabel='TIME', ylabel='VALUE1')
# move the legend
sns.move_legend(ax, bbox_to_anchor=(1.0, 0.5), loc='center left', frameon=False)
# constrain the x-axis limits to the number of seconds in a day
ax.set_xlim(0, 24 * 3600)
# create labels for every hour in the day, and add an extra spot for the last tick position
hours = [dtime(i).strftime('%H:%M') for i in range(24)] + ['']
# create xticks at every hour
ax.xaxis.set_major_locator(tkr.MultipleLocator(3600))
# set the ticks and corresponding labels; cut off extra starting and ending ticks to match labels
ax.set_xticks(ticks=ax.get_xticks()[1:-1], labels=hours, rotation=90)
# remove spines
ax.spines[['top', 'right']].set_visible(False)
plt.show()
How can I implement custom sorting in plotting daily data against a 24 hour axis which is given above so that x-axis start at 12:00:00 and end at 11:59:59. Please note that data should be reflected correctly, I mean shifting the time without shifting data simultaneously would be not helpful.
答案1
得分: 0
代替DATE_TIME,我应该在使用自定义排序时使用TIME!因此,在以下代码之后添加这行代码:
def custom_time_sorter(s):
s = pd.to_datetime(s)
return np.argsort(np.lexsort(展开收缩))
df = df.sort_values(by='TIME', key=custom_time_sorter)
之前的代码是:
df = df[(df['ID'] == 1) & (df['INSPECTION'].isin([1, 2, 3]))]
这样可以解决问题。
英文:
Instead of DATE_TIME, I should have used TIME when I use the custom sorting! So, adding this line:
def custom_time_sorter(s):
s = pd.to_datetime(s)
return np.argsort(np.lexsort(展开收缩))
df = df.sort_values(by='TIME', key=custom_time_sorter)
after
df = df[(df['ID'] == 1) & (df['INSPECTION'].isin([1, 2, 3]))]
solves the issue.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论