Matplotlib 混淆了小时和天

Matplotlib confuses hours and days

我正在尝试绘制一个 pandas DataFrame,其中时间戳作为索引,int 或 float 作为列:

Time Current_Gen1 Current_Gen2 Current_Gen3 Current_100A_110V Current_100A_220V Current_shore_power Gens_sum
2022-04-01 19:00:00 44.011111 0.0 42.833333 2.000000 19.055556 -0.066667 86.844444
2022-04-01 20:00:00 44.522222 0.0 43.616667 2.000000 17.861111 -0.155556 88.138889
2022-04-01 21:00:00 45.155556 0.0 44.705556 2.005556 18.616667 -0.161111 89.861111
2022-04-01 22:00:00 45.972222 0.0 45.372222 2.000000 19.133333 -0.277778 91.344444
2022-04-01 23:00:00 45.677778 0.0 45.755556 2.000000 20.744444 -0.377778 91.433333

我将它采样到小时以显示更少的点

我想显示日期的主要网格和小时的次要网格

如果让默认设置,我得到这个图:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv(r"data.csv", index_col=['Time'], parse_dates=['Time'])
df2 = df.resample('H').mean()

fig_gen_sum, axe = plt.subplots()
df2.plot(ax=axe, y='Gens_sum', grid=True)

default graph

第一期: 不明白为什么有一个日期有完整的描述

当我使用格式化程序获取日期时:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as dates

df = pd.read_csv(r"data.csv", index_col=['Time'], parse_dates=['Time'])
df2 = df.resample('H').mean()

fig_gen_sum, axe = plt.subplots()
df2.plot(ax=axe, y='Gens_sum', grid=True)

xax = axe.get_xaxis()
xax.set_major_formatter(dates.DateFormatter('%d-%m'))
xax.set_major_locator(dates.DayLocator())

day formatter graph

zoomed formatter graph

第二期:我得到一张图表,如果没看错的话,天数计为小时

我尝试过不同的配置,但结果总是很奇怪

我猜问题出在时间戳的格式上,但我找不到什么

@tdy在post

的评论中给出了回复

解决方案是将选项 x_compat=True 设置为:

df2.plot(ax=axe,x='time', y='Gens_sum', grid=True, x_compat=True)

如 pandas 文档中所述

Pandas includes automatic tick resolution adjustment for regular frequency time-series data. For limited cases where pandas cannot infer the frequency information (e.g., in an externally created twinx), you can choose to suppress this behavior for alignment purposes.

然后我可以得到这个结果:

其他所有内容,包括主要和次要刻度线也可以从那里工作:

fig_gen_sum, axe = plt.subplots()
df2.plot(ax=axe,x='time', y='Gens_sum', grid=True, x_compat=True)

xax = axe.get_xaxis()

xax.set_major_locator(dates.DayLocator())
xax.set_major_formatter(dates.DateFormatter('%y/%m/%d'))
xax.set_minor_locator(dates.HourLocator(interval=5))
xax.set_minor_formatter(dates.DateFormatter('%H h'))

给出: