如何使时间序列轴刻度和标签与数据点匹配

Posted

技术标签:

【中文标题】如何使时间序列轴刻度和标签与数据点匹配【英文标题】:How to make the timeseries axis ticks and labels match the data points 【发布时间】:2022-01-06 23:43:19 【问题描述】:

我已经通过手动设置我的 xticks 来绕过这个问题。 但是,我想了解这个“问题”背后的原因。

我有以下数据:

如您所见,我计算了我们每周广告系列的平均购物篮。 但是,如果我尝试绘制它,前几个日期会更改。

plt.figure(figsize=(16,6))

plt.plot(pd.to_datetime(avg_basket_pbm["trunc_usage_date"]), avg_basket_pbm["average_base_spend"], label="Monday Coupon Users")
plt.plot(pd.to_datetime(avg_basket_reg["TRUNC(EV.EFFECTIVE_DAY,'DD')"]), avg_basket_reg["average_base_spend"], label="Regular Coupon Users")
# plt.xticks(pd.to_datetime(avg_basket_pbm["trunc_usage_date"],format="%Y-%m-%d"), labels = avg_basket_pbm["trunc_usage_date"])
plt.title("Average Basket", weight = "bold", fontsize=14)
plt.legend()

这似乎只影响前几个日期,后面的日期保持不变。

可重现的例子:

from matplotlib import pyplot as plt
import numpy as np
import pandas as pd

dates = ['2021-10-11 00:00:00',
 '2021-10-18 00:00:00',
 '2021-10-25 00:00:00',
 '2021-11-01 00:00:00',
 '2021-11-08 00:00:00',
 '2021-11-15 00:00:00',
 '2021-11-22 00:00:00']


stamps = pd.to_datetime(dates)
vals = np.random.random(7)

plt.figure(figsize=(14,6))
plt.plot(stamps, vals)

【问题讨论】:

如果您正在绘制日期,刻度线在美学上是间隔开的,而不是标记您的数据。您的某些日期恰好位于审美边界上,但这是一种巧合(尝试将第 4 个日期设置为 2021-11-02,您会看到刻度没有变化)。 仅供参考:彻底回答问题非常耗时。如果您的问题已解决,请通过接受最适合您的需求的解决方案表示感谢。 ✔ 位于答案左上角的 ▲/▼ 箭头下方。如果出现更好的解决方案,则可以接受新的解决方案。如果您的声望超过 15,您也可以使用 ▲/▼ 箭头对答案的有用性进行投票。 如果解决方案无法回答问题,请发表评论。 What should I do when someone answers my question?。谢谢。 【参考方案1】:

Matplotlib 不会尝试将刻度与您的数据完全匹配,因为在大多数情况下看起来很糟糕。为了说明,我调整了您的示例并仅添加了四个数据点并强制 xticks 匹配数据:

from matplotlib import pyplot as plt
import numpy as np
import pandas as pd

dates = ['2021-10-11 00:00:00',
 '2021-10-18 00:00:00',
 '2021-10-25 00:00:00',
 '2021-11-01 00:00:00',
 '2021-11-08 00:00:00',
 '2021-11-09 00:00:00', # added
 '2021-11-10 00:00:00', # added
 '2021-11-11 00:00:00', # added
 '2021-11-12 00:00:00', # added
 '2021-11-15 00:00:00',
 '2021-11-22 00:00:00']


stamps = pd.to_datetime(dates)
vals = np.random.random(11)

plt.figure(figsize=(14,6))
plt.xticks(stamps, labels = dates)
plt.plot(stamps, vals)

刻度标签重叠且不可读。如果您将 plt.xticks 注释掉,matplotlib 可以“做自己的事情”,并将刻度放在它认为“合理”的地方。在这种特定情况下,它似乎是“每周一次,从每月 1 日开始”。如果您对您认为“合理”的刻度线位置有不同的意见/算法,那么您必须手动放置它们。

【讨论】:

确实有道理。但是,增加图形大小不会允许 plt 绘制“原始”刻度吗? 您可以拥有数千个数据点。一般来说,您不希望它们全部打勾。【参考方案2】: 绘制pandas.DataFrame 的正确方法是使用pandas.DataFrame.plot,它使用matplotlib 作为默认后端 pandas 调整刻度位置和标签以防止轴拥挤 指定 xticks= 参数以使日期刻度和标签与数据框中的日期相匹配,但这可能会导致轴拥挤,使其变得不可读。 python 3.9.7pandas 1.3.4matplotlib 3.5.0中测试
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

dates1 = ['2021-10-11 00:00:00', '2021-10-18 00:00:00', '2021-10-25 00:00:00', '2021-11-01 00:00:00', '2021-11-08 00:00:00', '2021-12-15 00:00:00', '2021-12-22 00:00:00']
dates2 = ['2021-10-12 00:00:00', '2021-10-19 00:00:00', '2021-10-26 00:00:00', '2021-11-02 00:00:00', '2021-11-09 00:00:00', '2021-12-16 00:00:00', '2021-12-23 00:00:00']
np.random.seed(365)
vals1 = np.random.random(7) * 200
vals2 = np.random.random(7) * 200

df1 = pd.DataFrame('date1': dates1, 'val1': vals1)
df2 = pd.DataFrame('date2': dates2, 'val2': vals2)

# convert the colmun to a datetime dtype
df1.date1 = pd.to_datetime(df1.date1).dt.date
df2.date2 = pd.to_datetime(df2.date2).dt.date

# plot the dataframe
ax = df1.plot(x='date1', marker='o', figsize=(12, 5))
df2.plot(x='date2', marker='o', ax=ax)

ax.set_title("Average Basket", weight="bold", fontsize=14)

指定xticks=df1.date1xticks=df2.date2,来自一个DataFrame 的所有日期都将在x 轴上。 两个 DataFrame 中的日期不相同。
ax = df1.plot(x='date1', marker='o', figsize=(12, 5))
df2.plot(x='date2', marker='o', ax=ax, xticks=df1.date1, rot=90, grid=True)

ax.set_title("Average Basket", weight="bold", fontsize=14)

将两个 DataFrame 中的日期组合起来用作xticks
# combine the dates to be used for xticks
xticks = df1.date1.tolist() + df2.date2.tolist()

# plot the dataframe
ax = df1.plot(x='date1', marker='o', figsize=(12, 5))
df2.plot(x='date2', marker='o', ax=ax, xticks=xticks, rot=90, grid=True)

ax.set_title("Average Basket", weight="bold", fontsize=14)

【讨论】:

以上是关于如何使时间序列轴刻度和标签与数据点匹配的主要内容,如果未能解决你的问题,请参考以下文章

如何解决重叠的轴刻度标签

Python,x轴标题与matplotlib中的刻度标签重叠

如何在python中更改日期时间数据的x轴刻度标签的频率

在ggplot2中更改轴文本的字体大小和方向

如何使用 Plotly 删除堆叠和分组条形图中的 x 轴刻度标签

如何在 Chart.js v2 中格式化 x 轴时间刻度值