如何让Pandas DataFrame直方图的月/日轴按时间顺序排列?
解决Pandas直方图横轴日/月按字母排序而非时间顺序的问题
这个问题我之前也碰到过!原因很简单:当你从datetime列提取日/月名称作为字符串后,Pandas会把它们当成普通的字符串变量,默认按字母排序。要解决这个问题,关键是把这些列转换成有序分类变量,指定正确的时间顺序就好啦。
核心思路
- 先定义好日/月的正确时间顺序列表(比如月份从1月到12月,星期从周一到周日,可根据你的需求调整起始顺序)
- 将提取出的日/月列转换为
pd.Categorical类型,指定categories为你定义的顺序,同时设置ordered=True - 再调用直方图绘制方法,此时横轴就会按时间顺序排列了
Jupyter Notebook 完整示例代码
import matplotlib.pyplot as plt import pandas as pd import numpy as np # 配置绘图参数 %matplotlib inline plt.rcParams["figure.figsize"] = (17, 8) plt.rcParams["font.size"] = 12 # 生成测试数据:包含datetime列的DataFrame np.random.seed(42) date_range = pd.date_range(start="2023-01-01", end="2023-12-31", freq="D") data = { "datetime": date_range, "value": np.random.randn(len(date_range)) * 10 + 50 } df = pd.DataFrame(data) # ---------------------- 处理月份名称并绘制直方图 ---------------------- # 定义月份的正确时间顺序 month_order = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] # 提取月份名称,并转换为有序分类 df["month_name"] = pd.Categorical( df["datetime"].dt.month_name(), categories=month_order, ordered=True ) # 绘制月份直方图 plt.subplot(1, 2, 1) df["month_name"].value_counts().plot(kind="bar", title="按月统计的直方图(时间顺序)") plt.xlabel("月份") plt.ylabel("数量") # ---------------------- 处理星期名称并绘制直方图 ---------------------- # 定义星期的正确时间顺序(这里以周一为第一天,可根据需求改为周日开头) weekday_order = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ] # 提取星期名称,并转换为有序分类 df["weekday_name"] = pd.Categorical( df["datetime"].dt.day_name(), categories=weekday_order, ordered=True ) # 绘制星期直方图 plt.subplot(1, 2, 2) df["weekday_name"].value_counts().plot(kind="bar", title="按星期统计的直方图(时间顺序)") plt.xlabel("星期") plt.ylabel("数量") plt.tight_layout() plt.show()
额外说明
- 如果你需要按数字格式的日/月(比如1-12月,1-31日),其实不需要转换分类,直接用
dt.month或dt.day提取数值即可,数值类型默认会按大小顺序排列 - 如果你的数据是小时区间(比如0-23点),同样提取
dt.hour数值类型就会自动按时间顺序排列,无需额外处理
内容的提问来源于stack exchange,提问作者BlandCorporation
相关产品推荐
相关产品推荐

