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()
#-----------------------------------------#
输出:
我已经修改了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()
#-----------------------------------------#
输出: