应用 DateFormatter 和 MonthLocator 后条形图上显示的不相关日期 在 Matplotlib 中为条形图设置日期时间 X 标签

问题描述

因此,我获得了“sample_date”列的频率图:https://stackoverflow.com/a/68420301/15934571
我只想显示每月的刻度。问题是应用 MonthLocator 和 DateFormatter 后 x 轴上的日期变成了不相关的日期(如 01-01-1970、01-02-1970 等)。我不知道为什么或如何解决它。将不胜感激任何帮助!

这是我的代码

import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv('dataset.csv')
data['sample_date'] = pd.to_datetime(data['sample_date'])

ax = data['sample_date'].value_counts().sort_index().plot(kind='bar') 

ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d-%m-%Y'))

以下是更大数据集的示例:

,sequence_name,sample_date,epi_week,epi_date,lineage
1,England/MILK-1647769/2021,2021-06-07,76,2021-06-06,C.37
2,England/MILK-156082C/2021,2021-05-06,71,2021-05-02,C.37
3,England/CAMC-149B04F/2021,2021-03-30,66,2021-03-28,C.37
4,England/CAMC-13962F4/2021,2021-03-04,62,2021-02-28,C.37
5,England/CAMC-13238EB/2021,2021-02-23,61,2021-02-21,C.37
0,England/PHEC-L304L78C/2021,2021-05-12,72,2021-05-09,B.1.617.3
1,England/MILK-15607D4/2021,B.1.617.3
2,England/MILK-156C77E/2021,2021-05-05,B.1.617.3
4,England/PHEC-K305K062/2021,2021-04-25,70,B.1.617.3
5,England/PHEC-K305K080/2021,B.1.617.3
6,England/ALDP-153351C/2021,2021-04-23,69,2021-04-18,B.1.617.3
7,England/PHEC-30C13B/2021,2021-04-22,B.1.617.3
8,England/PHEC-30AFE8/2021,B.1.617.3
9,England/PHEC-30A935/2021,2021-04-21,B.1.617.3
10,England/ALDP-152BC6D/2021,B.1.617.3
11,England/ALDP-15192D9/2021,2021-04-17,68,2021-04-11,B.1.617.3
12,England/ALDP-1511E0A/2021,2021-04-15,B.1.617.3
13,England/PHEC-306896/2021,2021-04-12,B.1.617.3
14,England/PORT-2DFB70/2021,2021-04-06,67,2021-04-04,B.1.617.3

解决方法

在 Matplotlib 中为条形图设置日期时间 X 标签

我不确定为什么 DateFormatter 不起作用,这可能与 pandas 设置 x_ticklabels 的方式有关。如果查看类中的 __ call __ 方法,它只是返回一个 num2date -> strftime 并返回一个日期时间的字符串。也许其他人可以评论为什么这不起作用,我很想知道。无论如何,您可以轻松地自行设置标签。

我发现您只对以 1 个月为间隔定位/标记月份感兴趣。这里的问题是,在条形图中,x_axis 不是连续的因变量。 x_axis 标记条形。由于它不是连续变量,因此很难说刻度应该位于何处。您可能需要手动执行此操作或使用不同的图表类型;例如散点图或直方图。

这是手动标记 xaxis 的示例。

enter image description here

data = pd.read_csv('stack_overflow.csv')
data['sample_date'] = pd.to_datetime(data['sample_date'])

df = data['sample_date'].value_counts().sort_index()
ax = df.plot(kind='bar') 

ax.set_xticks(np.arange(len(df)) - 0.75) #fixes offset made by rotation of labels
ax.set_xticklabels(df.index.strftime('%d-%m-%Y'),rotation=45)

#style plot
[ax.spines[s].set_visible(False) for s in ['top','right']]
ax.yaxis.set_major_locator(ticker.MultipleLocator(1))
ax.tick_params(axis='both',bottom=False,left=False)
ax.grid(axis='y',dashes=(8,3),color='gray',alpha=0.4)