Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib intelligent axis labels for timedelta

Tags:

matplotlib

I have a simple dataset of X and Y values I am plotting in matplotlib. The independent variable in my data is a duration/timedelta (e.g. 60 seconds, 2 hours, 24 hours, 10 days), which in my input data is always represented as an integer number of seconds. My question is, does matplotlib have any way of setting the duration axis labels intelligently, in a human readable form?

For example, at the small end of the scale, it would be desirable to show say 30 seconds simply as "30 seconds". At the large end of the scale, it would be nicer to show "10 days" rather than 864000 seconds. Somewhere in between, it would be better to have the labels read in "minutes" and "hours". Does matplotlib have any automated way of inferring something approximately human readable for durations spanning several orders of magnitude?

Ideally whatever approach I use should generalize to datasets that span different duration timescales, rather than a plot that is individually tailored to one input dataset.

like image 900
Bryce Thomas Avatar asked Mar 06 '13 05:03

Bryce Thomas


1 Answers

Could you provide an example? Is this what you want:

import datetime                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                               
import numpy as np                                                                                                                                                                                                                                                             
import pylab as plt                                                                                                                                                                                                                                                            
import matplotlib                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                               
fig = plt.figure()                                                                                                                                                                                                                                                             
ax = fig.add_subplot(111)                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                               
x = np.linspace(0, 300)  # 5 minutes                                                                                                                                                                                                                                                      
y = np.random.random(len(x))                                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                                                               
ax.plot(x, y)                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                               
def timeTicks(x, pos):                                                                                                                                                                                                                                                         
    d = datetime.timedelta(seconds=x)                                                                                                                                                                                                                                          
    return str(d)                                                                                                                                                                                                                                                              
formatter = matplotlib.ticker.FuncFormatter(timeTicks)                                                                                                                                                                                                                         
ax.xaxis.set_major_formatter(formatter)                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                               
plt.show()

Example output

It uses pythons timedelta. With 864000 seconds the above will result in "10 days, 10:00:00". You can of course stuff more advanced formatting into the timeTicks() function above.

like image 153
oystein Avatar answered Nov 06 '22 00:11

oystein