在Python/matplotlib中使用xaxis_date()手动设置xticks

2024-06-16 10:21:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在研究如何在x轴上绘制出与时间相对应的曲线图,并对其进行了很好的排序,其中一个奇怪的怪癖让我怀疑自己是否遇到了一个bug,或者(无可否认,更可能)正在做一些我不太明白的事情。

简单地说,下面是我的程序的简化版本。如果我把它放在一个.py文件中,并从解释器(ipython)中执行它,我会得到一个只有年份“2012”的x轴图形,重复多次,like this

但是,如果我注释掉手动设置xtick的行(40),即“plt.xticks(tk)”,然后在执行脚本后立即在解释器中运行确切的命令,那么它工作得很好,我的图看起来是like this

类似地,如果我将这一行移到脚本中savefig命令之后,也就是说将它放在文件的最末尾,那么它也可以工作。当然,在这两种情况下,只有在屏幕上绘制的图形具有所需的轴,而不是保存的文件。为什么我不能早点设置x轴?

感谢您的任何见解,提前感谢!

import matplotlib.pyplot as plt 
import datetime

# define arrays for x, y and errors
x=[16.7,16.8,17.1,17.4]
y=[15,17,14,16]
e=[0.8,1.2,1.1,0.9]

xtn=[]

# convert x to datetime format
for t in x:
   hours=int(t)
   mins=int((t-int(t))*60)
   secs=int(((t-hours)*60-mins)*60)
   dt=datetime.datetime(2012,01,01,hours,mins,secs)
   xtn.append(date2num(dt))

# set up plot
fig=plt.figure()
ax=fig.add_subplot(1,1,1)

# plot
ax.errorbar(xtn,y,yerr=e,fmt='+',elinewidth=2,capsize=0,color='k',ecolor='k')

# set x axis range
ax.xaxis_date()
t0=date2num(datetime.datetime(2012,01,01,16,35)) # x axis startpoint
t1=date2num(datetime.datetime(2012,01,01,17,35)) # x axis endpoint
plt.xlim(t0,t1) 

# manually set xtick values 
tk=[]
tk.append(date2num(datetime.datetime(2012,01,01,16,40)))
tk.append(date2num(datetime.datetime(2012,01,01,16,50)))
tk.append(date2num(datetime.datetime(2012,01,01,17,00)))
tk.append(date2num(datetime.datetime(2012,01,01,17,10)))
tk.append(date2num(datetime.datetime(2012,01,01,17,20)))
tk.append(date2num(datetime.datetime(2012,01,01,17,30)))
plt.xticks(tk)

plt.show()

# save to file
plt.savefig('savefile.png')

Tags: 文件datetime绘制pltax解释器tkint
1条回答
网友
1楼 · 发布于 2024-06-16 10:21:40

我认为您不需要调用xaxis_date();因为您已经以matplotlib知道如何处理的格式提供了x轴数据。我也认为你的公式有点问题。

我们可以使用matplotlib的内置格式化程序和定位器:

  1. 将主要xtick设置为定期间隔(分钟、小时、天等)
  2. 使用strftime格式字符串自定义显示

如果未指定格式化程序,则默认值是显示年份;这是您看到的。

试试这个:

import datetime as dt
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, MinuteLocator

x = [16.7,16.8,17.1,17.4]
y = [15,17,14,16]
e = [0.8,1.2,1.1,0.9]
xtn = []
for t in x:
  h = int(t)
  m = int((t-int(t))*60)
  xtn.append(dt.datetime.combine(dt.date(2012,1,1), dt.time(h,m)))

def larger_alim( alim ):
  ''' simple utility function to expand axis limits a bit '''
  amin,amax = alim
  arng = amax-amin
  nmin = amin - 0.1 * arng
  nmax = amax + 0.1 * arng
  return nmin,nmax

plt.errorbar(xtn,y,yerr=e,fmt='+',elinewidth=2,capsize=0,color='k',ecolor='k')
plt.gca().xaxis.set_major_locator( MinuteLocator(byminute=range(0,60,10)) )
plt.gca().xaxis.set_major_formatter( DateFormatter('%H:%M:%S') )
plt.gca().set_xlim( larger_alim( plt.gca().get_xlim() ) )
plt.show()

结果:

enter image description here

FWIW实用函数larger_alim最初是为另一个问题而编写的:Is there a way to tell matplotlib to loosen the zoom on the plotted data?

相关问题 更多 >