python - x 轴刻度作为日期
问题描述
我有一些数据要绘制,由两列组成,一列是金额count
,另一列是实际记录的日期。绘制此图时,由于我有超过 2000 个日期,因此不将每个日期都显示为 - 轴上的刻度更有意义x
,否则它将不可读。但是,我很难让日期x
以某种逻辑显示在 - 轴上。我曾尝试使用 matplotlib 的内置刻度定位器,但它无法以某种方式工作。这是数据的预览:
PatientTraffic = pd.DataFrame({'count' : CleanData.groupby("TimeStamp").size()}).reset_index()
display(PatientTraffic.head(3000))
TimeStamp count
0 2016-03-13 12:20:00 1
1 2016-03-13 13:39:00 1
2 2016-03-13 13:43:00 1
3 2016-03-13 16:00:00 1
4 2016-03-14 13:27:00 1
... ... ...
2088 2020-02-18 16:00:00 8
2089 2020-02-19 16:00:00 8
2090 2020-02-20 16:00:00 8
2091 2020-02-21 16:00:00 8
2092 2020-02-22 16:00:00 8
2093 rows × 2 columns
当我用这些设置来绘制它时:
PatientTrafficPerTimeStamp = PatientTraffic.plot.bar(
x='TimeStamp',
y='count',
figsize=(20,3),
title = "Patient Traffic over Time"
)
PatientTrafficPerTimeStamp.xaxis.set_major_locator(plt.MaxNLocator(3))
我希望得到一个条形图,其中x
-axis 有三个刻度,一个在开始中间和结束......也许我用错了。此外,似乎出现的刻度只是列中的前 3 个,这不是我想要的。任何帮助,将不胜感激!
解决方案
你可能认为你有一个问题,但实际上你有两个 - 两者都是基于你使用便利函数这一事实。您最可能不知道的问题是 pandas 将条形图绘制为分类数据。这在大多数情况下是有意义的,但显然不是,如果您将时间戳数据作为 x 轴。让我们看看我是否没有弥补:
import matplotlib.pyplot as plt
import pandas as pd
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
df = pd.read_csv("test.txt", sep = "\s{2,}", engine="python")
#convert TS from string into datetime objects
df.TS = pd.to_datetime(df.TS, format="%Y-%m-%d %H:%M:%S")
#and plot it as you do directly from pandas that provides the data to matplotlib
df.plot.bar(
x="TS",
y="Val",
ax=ax1,
title="pandas version"
)
#now plot the same data using matplotlib
ax2.bar(df.TS, df.Val, width=22)
ax2.tick_params(axis="x", labelrotation=90)
ax2.set_title("matplotlib version")
plt.tight_layout()
plt.show()
样本输出:
因此,我们应该直接从 matplotlib 中绘制它们,以防止丢失时间戳信息。显然,我们失去了 pandas 提供的一些便利,例如,我们必须调整条的宽度并标记轴。现在,您可以使用 的其他便利功能,MaxNLocator
但正如您注意到的那样,它已被编写为在大多数情况下都可以正常工作,但是您放弃了对刻度的精确定位的控制。为什么不使用 编写我们自己的定位器FixedLocator
?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.ticker import FixedLocator
import pandas as pd
def myownMaxNLocator(datacol, n):
datemin = mdates.date2num(datacol.min())
datemax = mdates.date2num(datacol.max())
xticks = np.linspace(datemin, datemax, n)
return xticks
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
df = pd.read_csv("test.txt", sep = "\s{2,}", engine="python")
df.TS = pd.to_datetime(df.TS, format="%Y-%m-%d %H:%M:%S")
df.plot.bar(
x="TS",
y="Val",
ax=ax1,
title="pandas version"
)
ax2.bar(df.TS, df.Val, width=22)
ax2.set_title("matplotlib version")
dateticks = myownMaxNLocator(df.TS, 5)
ax2.xaxis.set_major_locator(FixedLocator(dateticks))
ax2.tick_params(axis="x", labelrotation=90)
plt.tight_layout()
plt.show()
在这里,刻度以最低值开始,以最高值结束。或者,您可以使用LinearLocator
在整个视图中均匀分布刻度的 :
from matplotlib.ticker import LinearLocator
...
ax2.bar(df.TS, df.Val, width=22)
ax2.set_title("matplotlib version")
ax2.xaxis.set_major_locator(LinearLocator(numticks=5))
ax2.tick_params(axis="x", labelrotation=90)
...
样本数据存储在具有以下结构的文件中:
TS Val
0 2016-03-13 12:20:00 1
1 2016-04-13 13:39:00 3
2 2016-04-03 13:43:00 5
3 2016-06-17 16:00:00 1
4 2016-09-14 13:27:00 2
2088 2017-02-08 16:00:00 7
2089 2017-02-25 16:00:00 2
2090 2018-02-20 16:00:00 8
2091 2019-02-21 16:00:00 9
2092 2020-02-22 16:00:00 8
推荐阅读
- java - 登录请求后如何在移动应用中存储会话
- c# - C#:Math Round() 为不同的小数产生不同的值
- python - 使用预先确定的主题分布初始化 Gensim LDA 模型
- python - 将复选框存储到列表 tkinter
- firebase - 如何通过应用引擎监控firestore并同时执行多个游戏?
- command-line-interface - 如何使用 go lang 模板选项过滤 openshift pod?
- authentication - 为什么 Google Cloud Translate 无法提供持久性 503 服务?
- azure-data-factory-2 - Azure 数据工厂从 URL 保存 CSV
- amazon-web-services - 从另一个 AWS 账户访问 S3 Inventory
- python - 使用 importlib 加载模块时如何允许相对导入