简体   繁体   English

Matplotlib:如何为轴刻度和轴刻度标签获取相同的“基本”和“偏移”参数

[英]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: 这是情节:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM