我正在尝试格式化子图中的时间轴,以便xtick标签仅出现在数据开始之后。
import pandas as pd
import numpy as np
from datetime import date
import matplotlib.pyplot as plt
from matplotlib.dates import MonthLocator, num2date
from matplotlib.ticker import FuncFormatter
xs = [pd.date_range(f'{y}-07-01', '2021-12-31', freq='M')
for y in range(2016, 2019)]
ys = [np.random.rand(len(x)) for x in xs]
fig, axs = plt.subplots(3, 1, figsize=(10, 8))
for ax, x, y in zip(axs, xs, ys):
ax.plot(x, y)
# Custom formatting function
date_min = x[0].date()
def custom_date_formatter(x, pos):
dt = num2date(x)
if dt.date() < date_min:
return ''
elif dt.month == 1:
return dt.strftime('%Y')
else:
return dt.strftime('%b').upper()
ax.xaxis.set_major_locator(MonthLocator((1, 4, 7, 10)))
ax.xaxis.set_major_formatter(FuncFormatter(custom_date_formatter))
ax.tick_params(axis='x', labelsize=8)
ax.set_xlim(date(2016, 7, 1))
但我得到了一个所有轴都显示相同xtick标签的图:
但我希望他们是:
JUL - OCT - 2017 - APR - JUL - OCT - 2018 .....
..... JUL - OCT - 2018 - APR - JUL - OCT - 2019 .....
............ JUL - OCT - 2019 - APR - JUL - OCT - 2020 .....
我应该如何修复custom_date_formatter
函数来实现这一点?
1条答案
按热度按时间gudnpqoy1#
您遇到的问题是由于在循环中定义了函数,并且与所谓的closure有关
例如,考虑以下简化但基本相同的算法情况:
它给出了以下可能意外的输出(就像你的问题一样):
由于函数在循环的每次迭代中都被重新定义,当附加列表中的所有三个都被调用时,只有函数的最后一个定义保持定义-因此输出是相同的,而不是
0, 1, 2
。修改代码,将
custom_date_formatter
函数移出subplots axes循环