我想在matplotlib中针对日期范围绘制一系列值。我将tick base
参数更改为7,在每周的开头(plticker.IndexLocator, base = 7
)得到一个勾号。问题是set_xticklabels
函数不接受base
参数。因此,第二个刻度(代表第2周开始的第8天)在我的日期范围列表中标记为第2天,而不是第8天(见图)。
如何为set_xticklabels
提供base
参数?
以下是代码:
my_data = pd.read_csv("%r_filename_%s_%s_%d_%d.csv" % (num1, num2, num3, num4, num5), dayfirst=True)
my_data.plot(ax=ax1, color='r', lw=2.)
loc = plticker.IndexLocator(base=7, offset = 0) # this locator puts ticks at regular intervals
ax1.set_xticklabels(my_data.Date, rotation=45, rotation_mode='anchor', ha='right') # this defines the tick labels
ax1.xaxis.set_major_locator(loc)
以下是情节:
答案 0 :(得分:2)
非常感谢 - 您的解决方案完美无缺。对于其他人在未来遇到同样问题的情况:我已经实现了上述解决方案,但也添加了一些代码,以便刻度标签保持所需的旋转,并且还将(与其左端)对齐到相应的刻度。可能不是pythonic,可能不是最佳实践,但它有效
x_fmt = mpl.ticker.IndexFormatter(x)
ax.set_xticklabels(my_data.Date, rotation=-45)
ax.tick_params(axis='x', pad=10)
ax.xaxis.set_major_formatter(x_fmt)
labels = my_data.Date
for tick in ax.xaxis.get_majorticklabels():
tick.set_horizontalalignment("left")
答案 1 :(得分:1)
您的ticklabels变坏的原因是setting manual ticklabels decouples the labels from your data。正确的方法是根据您的需要使用Formatter
。由于每个数据点都有一个ticklabel列表,因此可以使用IndexFormatter
。它似乎没有在线记录,但它有一个帮助:
class IndexFormatter(Formatter)
| format the position x to the nearest i-th label where i=int(x+0.5)
| ...
| __init__(self, labels)
| ...
因此,您只需将日期列表传递给IndexFormatter
即可。使用最小的,独立于pandas的示例(仅用于生成虚拟数据的numpy):
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
# create dummy data
x = ['str{}'.format(k) for k in range(20)]
y = np.random.rand(len(x))
# create an IndexFormatter with labels x
x_fmt = mpl.ticker.IndexFormatter(x)
fig,ax = plt.subplots()
ax.plot(y)
# set our IndexFormatter to be responsible for major ticks
ax.xaxis.set_major_formatter(x_fmt)
即使刻度线位置发生变化,也应保持数据和标签配对:
我注意到你也在set_xticklabels
的调用中设置了ticklabels的旋转,你现在就会失去这个。我建议使用fig.autofmt_xdate
来代替这一点,它似乎是为了这个目的而设计的,而不会弄乱你的ticklabel数据。