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?

huangapple go评论81阅读模式
英文:

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?

问题

由于您只需要翻译代码部分,以下是您提供的代码的翻译:

  1. 感谢 @Trenton McKinney我知道如何在24小时坐标轴00:00 - 23:59:59上绘制每日数据[在这个问题中][1]在以下数据集中当我应用自定义排序**(custom_date_sorter函数)**图表不会按照custom_date_sorter函数中的顺序排列x我希望x轴从12:00:00开始结束于11:59:59
  2. import random
  3. import pandas as pd
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. import seaborn as sns
  7. import matplotlib.ticker as tkr
  8. from datetime import time as dtime
  9. random.seed(0)
  10. df = pd.DataFrame({'DATE_TIME': pd.date_range('2022-11-01', '2022-11-06 23:00:00', freq='20min'),
  11. 'ID': [random.randrange(1, 3) for n in range(430)]})
  12. df['VALUE1'] = [random.uniform(110, 160) for n in range(430)]
  13. df['VALUE2'] = [random.uniform(50, 80) for n in range(430)]
  14. df['INSPECTION'] = df['DATE_TIME'].dt.day
  15. # df['INSPECTION'] = df['INSPECTION'].replace(6, 1)
  16. # df['INSPECTION'] = df['INSPECTION'].replace(3, 1)
  17. df['MODE'] = np.select([df['INSPECTION'] == 1, df['INSPECTION'].isin([2, 3])], ['A', 'B'], 'C')
  18. df['TIME'] = df['DATE_TIME'].dt.time
  19. df['TIME'] = df['TIME'].astype('str')
  20. df['TIMEINTERVAL'] = df.DATE_TIME.diff().astype('timedelta64[m]')
  21. df['TIMEINTERVAL'] = df['TIMEINTERVAL'].fillna(0)
  22. def to_day_period(s):
  23. bins = ['0', '06:00:00', '13:00:00', '18:00:00', '23:00:00', '24:00:00']
  24. labels = ['Nighttime', 'Daytime', 'Daytime', 'Nighttime', 'Nighttime']
  25. return pd.cut(
  26. pd.to_timedelta(s),
  27. bins=list(map(pd.Timedelta, bins)),
  28. labels=labels, right=False, ordered=False
  29. )
  30. df['TIME_OF_DAY'] = to_day_period(df['TIME'])
  31. # ++++++++++++++++++++++++++++++++ sns plot ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  32. df = df[(df['ID'] == 1) & (df['INSPECTION'].isin([1, 2, 3]))]
  33. # +++++++++++++ CUSTOM SORTING +++++++++++++
  34. def custom_date_sorter(s):
  35. s = pd.to_datetime(s)
  36. return np.argsort(np.lexsort(
    展开收缩
    ))
  37. df = df.sort_values(by='DATE_TIME', key=custom_date_sorter)
  38. # +++++++++++++ ++++++++++++ +++++++++++++
  39. sns.set_style('darkgrid')
  40. sns.set(rc={'figure.figsize':(14,8)})
  41. # 添加一个列来存储总秒数
  42. df['total_seconds'] = df.DATE_TIME.apply(
  43. lambda row: (row - row.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds())
  44. # 遍历每个ID
  45. for id_ in sorted(df.ID.unique()):
  46. # 选择给定id_的数据
  47. data = df[df.ID.eq(id_)]
  48. # 创建一个图形
  49. fig = plt.figure(figsize=(10, 6)
  50. # 绘制数据
  51. ax = sns.lineplot(data=data, x='total_seconds', y='VALUE1', hue='INSPECTION', palette='viridis', legend='full')
  52. # 设置标题和标签
  53. ax.set(title=f'ID: {id_}', xlabel='TIME', ylabel='VALUE1')
  54. # 移动图例
  55. sns.move_legend(ax, bbox_to_anchor=(1.0, 0.5), loc='center left', frameon=False)
  56. # 限制x轴范围为一天的秒数
  57. ax.set_xlim(0, 24 * 3600)
  58. # 为一天中的每个小时创建标签,并添加一个额外的位置以匹配最后的刻度位置
  59. hours = [dtime(i).strftime('%H:%M') for i in range(24)] + ['']
  60. # 在每个小时创建xticks
  61. ax.xaxis.set_major_locator(tkr.MultipleLocator(3600))
  62. # 设置刻度和相应的标签;剪切掉多余的起始和结束刻度以匹配标签
  63. ax.set_xticks(ticks=ax.get_xticks()[1:-1], labels=hours, rotation=90)
  64. # 移除轴线
  65. ax.spines[['top', 'right']].set_visible(False)
  66. plt.show()

我如何在绘制每日数据对抗24小时轴时实现自定义排序,使x轴从12:00:00开始,结束于11:59:59。请注意,数据应正确反映,即不同时移动数据的时间不会有帮助。

  1. <details>
  2. <summary>英文:</summary>
  3. 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. :
  4. ```python
  5. import random
  6. import pandas as pd
  7. import numpy as np
  8. import matplotlib.pyplot as plt
  9. import seaborn as sns
  10. import matplotlib.ticker as tkr
  11. from datetime import time as dtime
  12. random.seed(0)
  13. df = pd.DataFrame({&#39;DATE_TIME&#39;: pd.date_range(&#39;2022-11-01&#39;, &#39;2022-11-06 23:00:00&#39;, freq=&#39;20min&#39;),
  14. &#39;ID&#39;: [random.randrange(1, 3) for n in range(430)]})
  15. df[&#39;VALUE1&#39;] = [random.uniform(110, 160) for n in range(430)]
  16. df[&#39;VALUE2&#39;] = [random.uniform(50, 80) for n in range(430)]
  17. df[&#39;INSPECTION&#39;] = df[&#39;DATE_TIME&#39;].dt.day
  18. # df[&#39;INSPECTION&#39;] = df[&#39;INSPECTION&#39;].replace(6, 1)
  19. # df[&#39;INSPECTION&#39;] = df[&#39;INSPECTION&#39;].replace(3, 1)
  20. df[&#39;MODE&#39;] = np.select([df[&#39;INSPECTION&#39;] == 1, df[&#39;INSPECTION&#39;].isin([2, 3])], [&#39;A&#39;, &#39;B&#39;], &#39;C&#39;)
  21. df[&#39;TIME&#39;] = df[&#39;DATE_TIME&#39;].dt.time
  22. df[&#39;TIME&#39;] = df[&#39;TIME&#39;].astype(&#39;str&#39;)
  23. df[&#39;TIMEINTERVAL&#39;] = df.DATE_TIME.diff().astype(&#39;timedelta64[m]&#39;)
  24. df[&#39;TIMEINTERVAL&#39;] = df[&#39;TIMEINTERVAL&#39;].fillna(0)
  25. def to_day_period(s):
  26. bins = [&#39;0&#39;, &#39;06:00:00&#39;, &#39;13:00:00&#39;, &#39;18:00:00&#39;, &#39;23:00:00&#39;, &#39;24:00:00&#39;]
  27. labels = [&#39;Nighttime&#39;, &#39;Daytime&#39;, &#39;Daytime&#39;, &#39;Nighttime&#39;, &#39;Nighttime&#39;]
  28. return pd.cut(
  29. pd.to_timedelta(s),
  30. bins=list(map(pd.Timedelta, bins)),
  31. labels=labels, right=False, ordered=False
  32. )
  33. df[&#39;TIME_OF_DAY&#39;] = to_day_period(df[&#39;TIME&#39;])
  34. # ++++++++++++++++++++++++++++++++ sns plot ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  35. df = df[(df[&#39;ID&#39;] == 1) &amp; (df[&#39;INSPECTION&#39;].isin([1, 2, 3]))]
  36. # +++++++++++++ CUSTOM SORTING +++++++++++++
  37. def custom_date_sorter(s):
  38. s = pd.to_datetime(s)
  39. return np.argsort(np.lexsort(
    展开收缩
    ))
  40. df = df.sort_values(by=&#39;DATE_TIME&#39;, key=custom_date_sorter)
  41. # +++++++++++++ ++++++++++++ +++++++++++++
  42. sns.set_style(&#39;darkgrid&#39;)
  43. sns.set(rc={&#39;figure.figsize&#39;:(14,8)})
  44. # add a column for total seconds
  45. df[&#39;total_seconds&#39;] = df.DATE_TIME.apply(
  46. lambda row: (row - row.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds())
  47. # iterate through each ID
  48. for id_ in sorted(df.ID.unique()):
  49. # select the data for the given id_
  50. data = df[df.ID.eq(id_)]
  51. # create a figure
  52. fig = plt.figure(figsize=(10, 6))
  53. # plot the data
  54. ax = sns.lineplot(data=data, x=&#39;total_seconds&#39;, y=&#39;VALUE1&#39;, hue=&#39;INSPECTION&#39;, palette=&#39;viridis&#39;, legend=&#39;full&#39;)
  55. # set the title and labels
  56. ax.set(title=f&#39;ID: {id_}&#39;, xlabel=&#39;TIME&#39;, ylabel=&#39;VALUE1&#39;)
  57. # move the legend
  58. sns.move_legend(ax, bbox_to_anchor=(1.0, 0.5), loc=&#39;center left&#39;, frameon=False)
  59. # constrain the x-axis limits to the number of seconds in a day
  60. ax.set_xlim(0, 24 * 3600)
  61. # create labels for every hour in the day, and add an extra spot for the last tick position
  62. hours = [dtime(i).strftime(&#39;%H:%M&#39;) for i in range(24)] + [&#39;&#39;]
  63. # create xticks at every hour
  64. ax.xaxis.set_major_locator(tkr.MultipleLocator(3600))
  65. # set the ticks and corresponding labels; cut off extra starting and ending ticks to match labels
  66. ax.set_xticks(ticks=ax.get_xticks()[1:-1], labels=hours, rotation=90)
  67. # remove spines
  68. ax.spines[[&#39;top&#39;, &#39;right&#39;]].set_visible(False)
  69. 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!因此,在以下代码之后添加这行代码:

  1. def custom_time_sorter(s):
  2. s = pd.to_datetime(s)
  3. return np.argsort(np.lexsort(
    展开收缩
    ))
  4. df = df.sort_values(by='TIME', key=custom_time_sorter)

之前的代码是:

  1. 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:

  1. def custom_time_sorter(s):
  2. s = pd.to_datetime(s)
  3. return np.argsort(np.lexsort(
    展开收缩
    ))
  4. df = df.sort_values(by=&#39;TIME&#39;, key=custom_time_sorter)

after

  1. df = df[(df[&#39;ID&#39;] == 1) &amp; (df[&#39;INSPECTION&#39;].isin([1, 2, 3]))]

solves the issue.

huangapple
  • 本文由 发表于 2023年4月11日 07:09:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75981358.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定