matplotlib 刻度与数据点不对齐

matplotlib ticks not align with data point

我已经修改了the example,但是如果设置nbins=10,x刻度标记位置似乎不正确!但如果设置 nbins=5 就可以正常工作。我怎么了?

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
from time import mktime
from datetime import datetime
from matplotlib.ticker import MaxNLocator
#%matplotlib inline
#-----------------------------------------#
def main():
    ticks = [ "9-28 11:07:57.435", "9-28 11:10:00.123", "9-28 11:40:00.654", "9-28 11:50:00.341", "9-28 12:00:00.773"]
    y = np.array([10, 12, 9, 15, 11])
    x = [mktime(datetime.strptime("2014-"+i, "%Y-%m-%d %H:%M:%S.%f").timetuple()) for i in ticks]
    plt.stem(x,y)
    plt.xticks(x, ticks,rotation=25,ha='right')
    plt.gca().xaxis.set_major_locator(MaxNLocator(nbins=10, prune = 'lower'))
    plt.gca().spines['right'].set_color('none')
    plt.gca().spines['top'].set_color('none')
    plt.gca().spines['left'].set_smart_bounds(True)
    plt.gca().spines['bottom'].set_smart_bounds(True)
    plt.gca().xaxis.set_ticks_position('bottom')
    plt.gca().yaxis.set_ticks_position('left')
    plt.show()
    return

#-----------------------------------------#
if __name__ == "__main__":
    main()

当您指定 plt.xticks 时,它所做的是将刻度定位器设置为 FixedLocator,允许您明确放置刻度。当您随后将刻度定位器分配给 MaxNLocator 时,您覆盖了显式刻度位置。

要获得最多 N 个刻度,您可以从刻度列表中提取 N 个值并将它们传递给 xticks,并消除手动设置定位器。例如,这些行从您当前的 5 个刻度列表中拉出 3 个刻度。

inds = np.linspace(0,len(ticks)-1,3).astype(int)
plt.xticks(np.array(x)[inds], np.array(ticks)[inds],rotation=25,ha='right')

一种解决方案如下:

#!/usr/bin/env python
#%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from time import mktime
from datetime import datetime

#-----------------------------------------#
def main():
    x = [
"9-28 11:07:57.435",
"9-28 11:10:00.123",
"9-28 11:40:00.654",
"9-28 11:50:00.341",
"9-28 12:00:00.773"
]
    y = np.array([10, 12, 9, 15, 11])
    dtlst = str2dt(x)
    plt.stem(dt2float(dtlst),y)
    bins = 5
    dtlst = list(linspace(dtlst[0],dtlst[-1],bins))
    plt.xticks(dt2float(dtlst),dt2str(dtlst),rotation=25,ha='right')
    plt.gca().spines['right'].set_color('none')
    plt.gca().spines['top'].set_color('none')
    plt.gca().spines['left'].set_smart_bounds(True)
    plt.gca().spines['bottom'].set_smart_bounds(True)
    plt.gca().xaxis.set_ticks_position('bottom')
    plt.gca().yaxis.set_ticks_position('left')
    plt.show()
    return

def str2dt(strlst):
    dtlst = [datetime.strptime("2014-"+i, "%Y-%m-%d %H:%M:%S.%f") for i in strlst]
    return dtlst

def dt2float(dtlst):
    floatlst = [mktime(dt.timetuple()) for dt in dtlst]
    return floatlst

def dt2str(dtlst):
    dtstr = [dt.strftime("%Y-%m-%d %H:%M:%S %Z%z") for dt in dtlst]
    return dtstr

def float2dt(floatlst):
    dtlst = [datetime.fromtimestamp(seconds) for seconds in floatlst]
    return dtlst

def linspace(start, end, bins):
    delta = (end - start)/bins
    x = start
    while x <= end:
        yield x
        x = x + delta
    return

#-----------------------------------------#
if __name__ == "__main__":
    main()
#-----------------------------------------#

输出: