绘制timedeltas的轴格式为DD HH:MM:SS与matplotlib

时间:2012-09-19 16:09:33

标签: datetime matplotlib timedelta axis-labels

我正在使用Matplotlib绘制赛车事件的速度/距离数据,例如距离与时间的关系,时间为水平轴,距离为垂直轴。

我的输入是两个向量,一个包含“从事件开始的秒数”中的时间值,另一个包含“到目前为止行进的距离”。同一情节中可能有很多运动员,所以我可以比较一下。

问题是,如果我绘制纯粹的时间,我会得到X轴的秒数,这是不自然的:

enter image description here

我可以根据实际日期和时间绘制数据,并且我得到可读结果,但这是绝对时间,而不是自事件开始以来经过的时间(这个时间从早上6点开始):

enter image description here

我想要的是以HMS格式获取已用时间的方法(与第二个图形相同,但是相对于事件开始的时间),并且可能具有缩放级别的“感知”(切换到小时:分钟,然后到几天:缩放级别更改时的小时数,以免因与尺度无关的数据太靠近而阻塞标签。)

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

我怀疑最简单的方法是编写自己的Formatterdoc)来转换为HMS。

import matplotlib

class myFormatter(matplotlib.ticker.Formatter):
    def __call__(self,in_value_in_seconds,pos=None):
        hours = int(in_value_in_seconds//(3600))
        in_value_in_seconds -= hours * 3600
        mins = int(in_value_in_seconds//(60))
        in_value_in_seconds -= mins * 60
        secs = int(in_value_in_seconds)

        return str(hours) + ":" + str(mins) + ":" + str(secs)

这是(我认为)最简单的情况,不支持任何缩放。将一些逻辑推入datetime.deltatime对象(或将它们作为参数)可能会更好。

结合MultipleLocatordoc),您可以很好地控制蜱的位置。

答案 1 :(得分:1)

我想出了以下内容,这就是我正在使用的内容。仍然不完美(不使用60的倍数作为主要滴答),但格式本身就是我想要的:

def HMS(seconds, pos):
    seconds = int(seconds)
    hours = seconds / 3600
    seconds -= 3600 * hours
    minutes = seconds / 60
    seconds -= 60 * minutes
    if hours == 0:
        if minutes == 0:
            return "%ds" % (seconds)
        return "%dm%02ds" % (minutes, seconds)
    return "%dh%02dm" % (hours, minutes)

ax = plt.gca()
ax.xaxis.set_major_formatter(plt.FuncFormatter(HMS))