[英]Matplotlib: How to get same “base” and “offset” parameters for axis ticks and axis tick labels
I want to plot a series of values against a date range in matplotlib. 我想针对matplotlib中的日期范围绘制一系列值。 I changed the tick
base
parameter to 7, to get one tick at the beginning of every week ( plticker.IndexLocator, base = 7
). 我将tick
base
参数更改为7,以在每个星期初获得一个tick( plticker.IndexLocator, base = 7
)。 The problem is that the set_xticklabels
function does not accept a base
parameter. 问题是
set_xticklabels
函数不接受base
参数。 As a result, the second tick (representing day 8 on the beginning of week 2) is labelled with day 2 from my date range list, and not with day 8 as it should be (see picture). 结果,第二个刻度(代表第2周开始的第8天)在我的日期范围列表中标有第2天,而不是应有的第8天(见图)。
How to give set_xticklabels
a base
parameter? 如何给
set_xticklabels
一个base
参数?
Here is the code: 这是代码:
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)
Here is the plot: 这是情节:
Many thanks - your solution perfectly works. 非常感谢-您的解决方案非常有效。 For the case that other people run into the same issue in the future: i have implemented the above-mentioned solution but also added some code so that the tick labels keep the desired rotation and also align (with their left end) to the respective tick.
对于将来其他人遇到相同问题的情况:我已经实现了上述解决方案,但是还添加了一些代码,以便刻度标签保持所需的旋转度并与各自的刻度对齐(与它们的左端对齐) 。 May not be pythonic, may not be best-practice, but it works
可能不是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")
The reason your ticklabels went bad is that setting manual ticklabels decouples the labels from your data . 您的剔号标签变坏的原因是, 设置手动剔号标签会使标签与数据脱钩 。 The proper approach is to use a
Formatter
according to your needs. 正确的方法是根据您的需要使用
Formatter
。 Since you have a list of ticklabels for each data point, you can use an IndexFormatter
. 由于您具有每个数据点的刻度标签列表,因此可以使用
IndexFormatter
。 It seems to be undocumented online, but it has a help: 它似乎没有在线记录,但有帮助:
class IndexFormatter(Formatter)
| format the position x to the nearest i-th label where i=int(x+0.5)
| ...
| __init__(self, labels)
| ...
So you just have to pass your list of dates to IndexFormatter
. 因此,您只需要将日期列表传递给
IndexFormatter
。 With a minimal, pandas-independent example (with numpy only for generating dummy data): 通过一个最小的,独立于熊猫的示例(仅使用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)
This should keep your data and labels paired even when tick positions change: 即使刻度位置发生变化,这也应使数据和标签保持配对:
I noticed you also set the rotation of the ticklabels in the call to set_xticklabels
, you would lose this now. 我注意到您还可以设置在调用ticklabels的旋转
set_xticklabels
,你现在失去了这个。 I suggest using fig.autofmt_xdate
to do this instead, it seems to be designed exactly for this purpose, without messing with your ticklabel data. 我建议改为使用
fig.autofmt_xdate
进行此操作,它似乎正是为此目的而设计的,而不会弄乱您的ticklabel数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.