matplotlib x轴刻度日期格式和位置

matplotlib x轴刻度日期格式和位置,matplotlib,Matplotlib,我尝试用matplotlib复制最初使用flotr2创建的用于pdf输出的打印图。我必须说flotr使用起来更容易。。。但除此之外,我目前一直在尝试将x轴上的日期/时间格式化为所需格式,即小时:分钟,间隔为2小时,如果x轴上的周期小于一天,则为年-月-日格式,如果周期大于1天,则为一天 我已经阅读了许多例子,并试图复制它们,但结果仍然是一样的,即小时:分钟:秒,根据周期的长短,间隔1到3小时 我的代码: colorMap = { 'speed': '#3388ff',

我尝试用matplotlib复制最初使用flotr2创建的用于pdf输出的打印图。我必须说flotr使用起来更容易。。。但除此之外,我目前一直在尝试将x轴上的日期/时间格式化为所需格式,即小时:分钟,间隔为2小时,如果x轴上的周期小于一天,则为年-月-日格式,如果周期大于1天,则为一天

我已经阅读了许多例子,并试图复制它们,但结果仍然是一样的,即小时:分钟:秒,根据周期的长短,间隔1到3小时

我的代码:

colorMap = {
        'speed': '#3388ff',
        'fuel': '#ffaa33',
        'din1': '#3bb200',
        'din2': '#ff3333',
        'satellites': '#bfbfff'
}

otherColors = ['#00A8F0','#C0D800','#CB4B4B','#4DA74D','#9440ED','#800080','#737CA1','#E4317F','#7D0541','#4EE2EC','#6698FF','#437C17','#7FE817','#FBB117']

plotMap = {}

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as dates
fig = plt.figure(figsize=(22, 5), dpi = 300, edgecolor='k')
ax1 = fig.add_subplot(111)

realdata = data['data']
keys = realdata.keys()
if 'speed' in keys:
    speed_index = keys.index('speed')
    keys.pop(speed_index)
    keys.insert(0, 'speed')

i = 0
for key in keys:
    if key not in colorMap.keys():
        color = otherColors[i]
        otherColors.pop(i)
        colorMap[key] = color
        i += 1

label = u'%s' % realdata[keys[0]]['name']
ax1.set_ylabel(label)

plotMap[keys[0]] = {}
plotMap[keys[0]]['label'] = label

first_dates = [ r[0] for r in realdata[keys[0]]['data']]

date_range = first_dates[-1] - first_dates[0]


ax1.xaxis.reset_ticks()

if date_range > datetime.timedelta(days = 1):
    ax1.xaxis.set_major_locator(dates.WeekdayLocator(byweekday = 1, interval=1))
    ax1.xaxis.set_major_formatter(dates.DateFormatter('%Y-%m-%d'))
else:
    ax1.xaxis.set_major_locator(dates.HourLocator(byhour=range(24), interval=2))
    ax1.xaxis.set_major_formatter(dates.DateFormatter('%H:%M'))

ax1.xaxis.grid(True)

plotMap[keys[0]]['plot'] = ax1.plot_date(
                                dates.date2num(first_dates), 
                                [r[1] for r in realdata[keys[0]]['data']], colorMap[keys[0]], xdate=True)

if len(keys) > 1:
    first = True
    for key in keys[1:]:
        if first:
            ax2 = ax1.twinx()
            ax2.set_ylabel(u'%s' % realdata[key]['name'])
            first = False
        plotMap[key] = {}
        plotMap[key]['label'] = u'%s' % realdata[key]['name']
        plotMap[key]['plot'] = ax2.plot_date(
                                    dates.date2num([ r[0] for r in realdata[key]['data']]), 
                                    [r[1] for r in realdata[key]['data']], colorMap[key], xdate=True)


plt.legend([value['plot'] for key, value in plotMap.iteritems()], [value['label'] for key, value in plotMap.iteritems()], loc = 2)

plt.savefig(path +"node.png", dpi = 300, bbox_inches='tight')
有人能指出为什么我没有得到想要的结果吗

编辑1:

我在绘图后移动了格式化块,现在似乎得到了更好的结果。不过,它们现在仍然是理想的结果。若周期小于一天,那个么我每2小时(间隔=2)就会得到一次滴答声,但我希望我能在偶数小时而不是不均匀的时间得到这些滴答声。可能吗

if date_range > datetime.timedelta(days = 1):
    xax.set_major_locator(dates.DayLocator(bymonthday=range(1,32), interval=1))
    xax.set_major_formatter(dates.DateFormatter('%Y-%m-%d'))
else:
    xax.set_major_locator(dates.HourLocator(byhour=range(24), interval=2))
    xax.set_major_formatter(dates.DateFormatter('%H:%M'))
编辑2: 这似乎给了我想要的:

if date_range > datetime.timedelta(days = 1):
    xax.set_major_locator(dates.DayLocator(bymonthday=range(1,32), interval=1))
    xax.set_major_formatter(dates.DateFormatter('%Y-%m-%d'))
else:
    xax.set_major_locator(dates.HourLocator(byhour=range(0,24,2)))
    xax.set_major_formatter(dates.DateFormatter('%H:%M'))

艾伦

你让这条路变得比你需要的更难了
matplotlib
可以直接针对
datetime
对象进行打印。我怀疑您的问题是您正在设置定位器,然后进行打印,并且打印正在使用默认的自动版本替换定位器/格式设置程序。尝试将有关定位器的逻辑块移动到绘图循环的下方

我认为这可能会取代您代码中的一大部分:

d = datetime.timedelta(minutes=2)
now =  datetime.datetime.now()
times = [now + d * j for j in range(500)]
ax = plt.gca() # get the current axes
ax.plot(times, range(500))

xax = ax.get_xaxis() # get the x-axis
adf = xax.get_major_formatter() # the the auto-formatter


adf.scaled[1./24] = '%H:%M'  # set the < 1d scale to H:M
adf.scaled[1.0] = '%Y-%m-%d' # set the > 1d < 1m scale to Y-m-d
adf.scaled[30.] = '%Y-%m' # set the > 1m < 1Y scale to Y-m
adf.scaled[365.] = '%Y' # set the > 1y scale to Y

plt.draw()
d=datetime.timedelta(分钟=2)
now=datetime.datetime.now()
时间=[现在+d*j表示范围内的j(500)]
ax=plt.gca()#获取当前轴
ax.绘图(次数,范围(500))
xax=ax.get_xaxis()#获取x轴
adf=xax.get_major_formatter()#自动格式化程序
adf.scaled[1./24]='%H:%M'#将<1d比例设置为H:M
adf.缩放[1.0]=“Y-%m-%d”#将>1d<1m的缩放设置为Y-m-d
adf.scaled[30.]='%Y-%m'#将大于1m<1Y的比例设置为Y-m
adf.scaled[365.]='%Y'#将>1y比例设置为Y
plt.draw()

通过这样做,我实现了我想要的:

if date_range > datetime.timedelta(days = 1):
    xax.set_major_locator(dates.DayLocator(bymonthday=range(1,32), interval=1))
    xax.set_major_formatter(dates.DateFormatter('%Y-%m-%d'))
else:
    xax.set_major_locator(dates.HourLocator(byhour=range(0,24,2)))
    xax.set_major_formatter(dates.DateFormatter('%H:%M'))

谢谢这是有效的(没有错误!)。。。但事实并非如此。它似乎没有进行格式化:当我打开的时段超过一天时,我不会得到%Y-%m-%d格式,而是得到了%H:%m:%S格式,而该格式没有在任何地方指定。我在打印后移动了自己的格式块,现在似乎得到了更好的结果-尽管它们仍然不是期望的结果。你是否将键复制为浮点(不是整数)?我不明白你在说什么键(浮点?整数?)。无论如何,我得到了我所需要的:)@Zayatzz您使用的mpl版本是什么?@BrentFaust问题是您的格式化程序是
ScalarFormatter
而不是
AutoDateFormatter
以上的代码都是假设的。您有解决过这个问题吗?是的,实际上我有。如果你看一下edit2,你就可以看到是什么给了我我想要的。你应该把edit2作为答案,然后接受它。这会将问题标记为已解决,这将比在问题中找到解决方案更能帮助未来用户(并且您可以从您的答案中获得代表)。