如何在x轴上绘制datetime.time

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

How to plot datetime.time on x-axis

问题

  1. import pandas as pd
  2. import matplotlib.pyplot as plt
  3. # 示例数据框
  4. data = {'Id': [1503960366, 1503960366, 1503960366, 1503960366, 1503960366],
  5. 'ActivityHour': ['2016-04-12 00:00:00', '2016-04-12 01:00:00', '2016-04-12 02:00:00', '2016-04-12 03:00:00', '2016-04-12 04:00:00'],
  6. 'Calories': [81, 61, 59, 47, 48],
  7. 'TotalIntensity': [20, 8, 7, 0, 0],
  8. 'AverageIntensity': [0.333333, 0.133333, 0.116667, 0.0, 0.0],
  9. 'StepTotal': [373, 160, 151, 0, 0]}
  10. hourly_activity = pd.DataFrame(data)
  11. hourly_activity['time'] = [d.time() for d in hourly_activity['ActivityHour']]
  12. hourly_activity['date'] = [d.date() for d in hourly_activity['ActivityHour']]
  13. hours_vs_steps = hourly_activity.copy()
  14. hours_vs_steps = hours_vs_steps[['time', 'StepTotal', 'Calories']]
  15. hours_vs_steps = hours_vs_steps.groupby(['time']).sum()
  16. hours_vs_steps.reset_index(inplace=True)
  17. # 初始数据框
  18. Id ActivityHour Calories TotalIntensity AverageIntensity StepTotal
  19. 0 1503960366 2016-04-12 00:00:00 81 20 0.333333 373
  20. 1 1503960366 2016-04-12 01:00:00 61 8 0.133333 160
  21. 2 1503960366 2016-04-12 02:00:00 59 7 0.116667 151
  22. 3 1503960366 2016-04-12 03:00:00 47 0 0.000000 0
  23. 4 1503960366 2016-04-12 04:00:00 48 0 0.000000 0
  24. # 使用.groupby后的数据框
  25. time StepTotal Calories
  26. 0 00:00:00 39404 67066
  27. 1 01:00:00 21555 65464
  28. 2 02:00:00 15964 64551
  29. 3 03:00:00 5996 63013
  30. 4 04:00:00 11836 63620
  31. # 绘制图表时的代码
  32. plt.plot(hours_vs_steps.time, hours_vs_steps.StepTotal)

结果会导致以下错误:

  1. ---------------------------------------------------------------------------
  2. TypeError Traceback (most recent call last)
  3. Cell In[28], line 1
  4. ----> 1 plt.plot(hours_vs_steps.time, hours_vs_steps.StepTotal)
  5. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\pyplot.py:2812, in plot(scalex, scaley, data, *args, **kwargs)
  6. 2810 @_copy_docstring_and_deprecators(Axes.plot)
  7. 2811 def plot(*args, scalex=True, scaley=True, data=None, **kwargs):
  8. -> 2812 return gca().plot(
  9. 2813 *args, scalex=scalex, scaley=scaley,
  10. 2814 **({"data": data} if data is not None else {}), **kwargs)
  11. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\axes\_axes.py:1690, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
  12. 1688 lines = [*self._get_lines(*args, data=data, **kwargs)]
  13. 1689 for line in lines:
  14. -> 1690 self.add_line(line)
  15. 1691 if scalex:
  16. 1692 self._request_autoscale_view("x")
  17. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\axes\_base.py:2304, in _AxesBase.add_line(self, line)
  18. 2301 if line.get_clip_path() is None:
  19. 2302 line.set_clip_path(self.patch)
  20. -> 2304 self._update_line_limits(line)
  21. 2305 if not line.get_label():
  22. 2306 line.set_label(f'_child{len(self._children)}')
  23. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\axes\_base.py:2327, in _AxesBase._update_line_limits(self, line)
  24. 2323 def _update_line_limits(self, line):
  25. 2324 """
  26. 2325 Figures out the data limit of the given line, updating self.dataLim.
  27. 2326 """
  28. -> 2327 path = line.get_path()
  29. 2328 if path.vertices.size == 0:
  30. 2329 return
  31. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\lines.py:1029, in Line2D.get_path(self)
  32. 1027 """Return the `~matplotlib.path.Path` associated with this line."""
  33. 1028 if self._invalidy or self._invalidx:
  34. -> 1029 self.recache()
  35. 1030 return self._path
  36. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\lines.py:657, in Line2D.recache(self, always)
  37. 655 if always or self._invalidx:
  38. 656 xconv = self.convert_xunits(self._xorig)
  39. --> 657 x = _to_unmasked_float_array(xconv).ravel()
  40. 658 else:
  41. 659 x = self._x
  42. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\cbook\__init__.py:1335, in _to_unmasked_float_array(x)
  43. 1333 return np.ma.asarray(x, float).filled(np.nan)
  44. 1334 else:
  45. -> 1335 return np.asarray(x, float)
  46. TypeError: float() argument must be a string or a real number, not 'datetime.time'
英文:

I'm trying to compare the usage of a device during certain hours. My dataset provided a date-time format (YYYY/MM/D HH:MM:SS) that I split in two columns and then grouped by the new time column to get the summary of steps per hour.

  1. import pandas as pd
  2. import matplotlib.pyplot as plt
  3. # sample dataframe
  4. data = {'Id': [1503960366, 1503960366, 1503960366, 1503960366, 1503960366],
  5. 'ActivityHour': ['2016-04-12 00:00:00', '2016-04-12 01:00:00', '2016-04-12 02:00:00', '2016-04-12 03:00:00', '2016-04-12 04:00:00'],
  6. 'Calories': [81, 61, 59, 47, 48],
  7. 'TotalIntensity': [20, 8, 7, 0, 0],
  8. 'AverageIntensity': [0.333333, 0.133333, 0.116667, 0.0, 0.0],
  9. 'StepTotal': [373, 160, 151, 0, 0]}
  10. hourly_activity = pd.DataFrame(data)
  11. hourly_activity['time'] = [d.time() for d in hourly_activity['ActivityHour']]
  12. hourly_activity['date'] = [d.date() for d in hourly_activity['ActivityHour']]
  13. hours_vs_steps = hourly_activity.copy()
  14. hours_vs_steps = hours_vs_steps[['time', 'StepTotal', 'Calories']]
  15. hours_vs_steps = hours_vs_steps.groupby(['time']).sum()
  16. hours_vs_steps.reset_index(inplace=True)

Initial DataFrame:

  1. Id ActivityHour Calories TotalIntensity AverageIntensity StepTotal
  2. 0 1503960366 2016-04-12 00:00:00 81 20 0.333333 373
  3. 1 1503960366 2016-04-12 01:00:00 61 8 0.133333 160
  4. 2 1503960366 2016-04-12 02:00:00 59 7 0.116667 151
  5. 3 1503960366 2016-04-12 03:00:00 47 0 0.000000 0
  6. 4 1503960366 2016-04-12 04:00:00 48 0 0.000000 0

After .groupby:

  1. time StepTotal Calories
  2. 0 00:00:00 39404 67066
  3. 1 01:00:00 21555 65464
  4. 2 02:00:00 15964 64551
  5. 3 03:00:00 5996 63013
  6. 4 04:00:00 11836 63620

I tried many times to plot the "StepTotal column as y_axis while using the time columns as x_axis but I wasn't able to do it either using matplotlib or seaborn.

Also, tried to plot the time when had it as index using hours_vs_steps.index but didn't work.

  1. plt.plot(hours_vs_steps.time, hours_vs_steps.StepTotal)

Results in the following error

  1. ---------------------------------------------------------------------------
  2. TypeError Traceback (most recent call last)
  3. Cell In[28], line 1
  4. ----> 1 plt.plot(hours_vs_steps.time, hours_vs_steps.StepTotal)
  5. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\pyplot.py:2812, in plot(scalex, scaley, data, *args, **kwargs)
  6. 2810 @_copy_docstring_and_deprecators(Axes.plot)
  7. 2811 def plot(*args, scalex=True, scaley=True, data=None, **kwargs):
  8. -> 2812 return gca().plot(
  9. 2813 *args, scalex=scalex, scaley=scaley,
  10. 2814 **({"data": data} if data is not None else {}), **kwargs)
  11. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\axes\_axes.py:1690, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
  12. 1688 lines = [*self._get_lines(*args, data=data, **kwargs)]
  13. 1689 for line in lines:
  14. -> 1690 self.add_line(line)
  15. 1691 if scalex:
  16. 1692 self._request_autoscale_view("x")
  17. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\axes\_base.py:2304, in _AxesBase.add_line(self, line)
  18. 2301 if line.get_clip_path() is None:
  19. 2302 line.set_clip_path(self.patch)
  20. -> 2304 self._update_line_limits(line)
  21. 2305 if not line.get_label():
  22. 2306 line.set_label(f'_child{len(self._children)}')
  23. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\axes\_base.py:2327, in _AxesBase._update_line_limits(self, line)
  24. 2323 def _update_line_limits(self, line):
  25. 2324 """
  26. 2325 Figures out the data limit of the given line, updating self.dataLim.
  27. 2326 """
  28. -> 2327 path = line.get_path()
  29. 2328 if path.vertices.size == 0:
  30. 2329 return
  31. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\lines.py:1029, in Line2D.get_path(self)
  32. 1027 """Return the `~matplotlib.path.Path` associated with this line."""
  33. 1028 if self._invalidy or self._invalidx:
  34. -> 1029 self.recache()
  35. 1030 return self._path
  36. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\lines.py:657, in Line2D.recache(self, always)
  37. 655 if always or self._invalidx:
  38. 656 xconv = self.convert_xunits(self._xorig)
  39. --> 657 x = _to_unmasked_float_array(xconv).ravel()
  40. 658 else:
  41. 659 x = self._x
  42. File ~\anaconda3\envs\py11\Lib\site-packages\matplotlib\cbook\__init__.py:1335, in _to_unmasked_float_array(x)
  43. 1333 return np.ma.asarray(x, float).filled(np.nan)
  44. 1334 else:
  45. -> 1335 return np.asarray(x, float)
  46. TypeError: float() argument must be a string or a real number, not 'datetime.time'

答案1

得分: 2

  • 使用 pandas.DataFrame.plot 直接绘制数据框,该方法使用 matplotlib 作为后端。
  • 使用 .dt 访问器 提取时间和日期组件,而不是使用列表推导。
  • python 3.11.3pandas 2.0.1matplotlib 3.7.1 中测试通过
  1. import pandas as pd
  2. # 假设有名为 df 的样本数据框
  3. df = pd.DataFrame(data)
  4. # 将列转换为 datetime[ns] 类型
  5. df.ActivityHour = pd.to_datetime(df.ActivityHour)
  6. # 根据需要提取时间和日期
  7. df['time'] = df.ActivityHour.dt.time
  8. df['date'] = df.ActivityHour.dt.date
  9. # 分组并求和
  10. dfg = df.groupby(['time'])[['StepTotal', 'Calories']].sum()
  11. # 使用 pandas.DataFrame.plot 绘制图表
  12. ax = dfg.plot(secondary_y='Calories', figsize=(9, 5))

如何在x轴上绘制datetime.time

英文:
  • Plot the dataframe directly with pandas.DataFrame.plot, which uses matplotlib as the backend.
  • Use the .dt accessor to extract the time and date components, not a list comprehension.
  • Tested in python 3.11.3, pandas 2.0.1, matplotlib 3.7.1
  1. import pandas as pd
  2. # given the sample dataframe as df
  3. df = pd.DataFrame(data)
  4. # convert the column to a datetime[ns] Dtype
  5. df.ActivityHour = pd.to_datetime(df.ActivityHour)
  6. # extract the time and date as needed
  7. df['time'] = df.ActivityHour.dt.time
  8. df['date'] = df.ActivityHour.dt.date
  9. # group and sum
  10. dfg = df.groupby(['time'])[['StepTotal', 'Calories']].sum()
  11. # plot with pandas.DataFrame.plot
  12. ax = dfg.plot(secondary_y='Calories', figsize=(9, 5))

如何在x轴上绘制datetime.time

huangapple
  • 本文由 发表于 2023年5月28日 17:05:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76350723.html
匿名

发表评论

匿名网友

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

确定