使用set_major_formatter后X轴原点重置为1970-01-01的问题
解决Pandas柱状图日期格式设置后X轴重置为1970-01-01的问题
问题原因
Pandas绘制柱状图时,会自动将日期索引转换为分类变量(X轴实际存储的是整数位置,比如0、1、2...),而matplotlib.dates.DateFormatter是用来解析时间戳数值(从1970-01-01开始的毫秒/秒数)的。直接给X轴绑定这个formatter时,它会把分类变量的整数位置误判为时间戳,导致X轴原点重置为1970-01-01。
方法一:手动设置刻度标签(适配Pandas柱状图逻辑)
不用DateFormatter,直接提取对应刻度位置的日期并格式化:
import pandas as pd import matplotlib.pyplot as plt import matplotlib.dates as mdates dates = pd.date_range(start="2021-01-01", end="2022-12-01") data = [d.day for d in dates] df = pd.DataFrame(index=dates, columns=["Data"], data=data) # 绘制柱状图并获取轴对象 ax = df.plot(kind="bar") # 定义主刻度的月份(季度初) major_months = mdates.MonthLocator(bymonth=(1, 4, 7, 10)) # 获取这些月份对应的日期在DataFrame索引中的位置 major_positions = [df.index.get_loc(date) for date in major_months.tick_values(df.index.min(), df.index.max())] # 设置主刻度位置 ax.xaxis.set_major_locator(plt.FixedLocator(major_positions)) # 将主刻度标签格式化为%Y-%m ax.set_xticklabels([df.index[pos].strftime("%Y-%m") for pos in major_positions]) # 设置次刻度(每月初)的位置 minor_months = mdates.MonthLocator() minor_positions = [df.index.get_loc(date) for date in minor_months.tick_values(df.index.min(), df.index.max())] ax.xaxis.set_minor_locator(plt.FixedLocator(minor_positions)) plt.tight_layout() plt.show()
方法二:直接用Matplotlib绘制柱状图(绕过Pandas分类索引)
直接使用plt.bar,让X轴存储时间戳数值,这样就能正常使用DateFormatter:
import pandas as pd import matplotlib.pyplot as plt import matplotlib.dates as mdates from matplotlib.dates import DateFormatter dates = pd.date_range(start="2021-01-01", end="2022-12-01") data = [d.day for d in dates] df = pd.DataFrame(index=dates, columns=["Data"], data=data) fig, ax = plt.subplots() # 用Matplotlib原生bar绘图,X轴传入日期索引(会自动转为时间戳数值) ax.bar(df.index, df["Data"]) # 设置主/次刻度定位器 ax.xaxis.set_major_locator(mdates.MonthLocator(bymonth=(1, 4, 7, 10))) ax.xaxis.set_minor_locator(mdates.MonthLocator()) # 设置日期格式 date_form = DateFormatter("%Y-%m") ax.xaxis.set_major_formatter(date_form) # 旋转X轴标签避免重叠 plt.xticks(rotation=45) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者garyfritz
相关产品推荐
相关产品推荐

