matplotlib:以美观和动态的格式绘制持续时间

1 投票
2 回答
608 浏览
提问于 2025-04-16 21:11

我需要制作一个图表,横轴是日期,纵轴是时间的持续时长。我希望纵轴的格式能智能一些。我的数据格式是这样的:'0:00:02.994000'(表示0小时、0分钟、2秒和994000微秒)。

这些数据的范围可能从几秒到超过12小时不等,不过一般来说,对于每个图表,大部分数据点会在同一单位内(秒、分钟或小时)。

问题是,有时候会出现一些特殊值,它们的单位和其他数据点不同。比如,可能有一个图表大部分的持续时间在1到3小时之间,但偶尔会出现5分钟或者30秒的数据点。又或者,另一个图表大部分数据点是以分钟为单位,但偶尔会有一些长时间或短时间的数据点以小时或秒为单位。

我想找到一个好的(动态的)方式来格式化纵轴。有两个问题:

1) 我是否应该分析数据,看看大多数数据点使用的是什么单位,然后用这个单位作为纵轴的单位?也就是说,如果大多数是以分钟为单位的持续时间,那么纵轴就应该用分钟表示。如果大多数是小时,那么纵轴就用小时,等等……这样格式化会更适合显示的数据类型。

2) 如果一个图表的纵轴单位是分钟(因为第一点的原因),但用户想要放大查看一个只有几秒的数据点,我希望格式化工具能把纵轴的刻度改为秒。我不想在纵轴上显示像“0.0335”分钟这样的数字,而是希望显示成“2秒”。

如果有任何建议来处理这个问题,我会非常感激。谢谢,Che

2 个回答

0

我做这个的方法是使用datetime.timedelta的字符串格式化,你可以这样创建格式化器:

def timeTicks(x, pos):
    d = datetime.timedelta(seconds=x)
    return str(d)
formatter = matplotlib.ticker.FuncFormatter(timeTicks)

然后可以通过 ax.xaxis.set_major_formatter(formatter) 把它应用到坐标轴上,这样当用户放大时,格式会自动调整。需要注意的是,这个方法并没有解决大多数问题,但可能对其他类似情况的人有帮助。

0

你可以注册一个事件处理程序,根据ylim来调整y数据。

fig = plt.figure()
ax = fig.add_subplot(111)
ylim = ax.get_ylim()
scale = get_scale(ylim)
def tweak_y(event):
    new_ylim = ax.get_ylim() 
    if new_ylim == ylim:
        return
    ylim = new_ylim
    if get_scale(ylim) != scale:
        # tweak ydata and replot
        pass

cid = fig.canvas.mpl_connect('draw_event', tweak_y)

撰写回答