Search code examples
pythonmatplotlibx-axis

How to specify time locator's start-ticking timestamp


All I want is quite straight forward, I just want the locator ticks to start at a specified timestamp:
peudo code: locator.set_start_ticking_at( datetime_dummy )
I have no luck finding anything so far.

Here is the portion of the code for this question:

    axes[0].set_xlim(datetime_dummy) # datetime_dummy = '2015-12-25 05:34:00'
    import matplotlib.dates as matdates
    seclocator = matdates.SecondLocator(interval=20) 
    minlocator = matdates.MinuteLocator(interval=1) 
    hourlocator = matdates.HourLocator(interval=12)

    seclocator.MAXTICKS  = 40000
    minlocator.MAXTICKS  = 40000
    hourlocator.MAXTICKS  = 40000

    majorFmt = matdates.DateFormatter('%Y-%m-%d, %H:%M:%S')  
    minorFmt = matdates.DateFormatter('%H:%M:%S')  

    axes[0].xaxis.set_major_locator(minlocator)
    axes[0].xaxis.set_major_formatter(majorFmt)
    plt.setp(axes[0].xaxis.get_majorticklabels(), rotation=90 )

    axes[0].xaxis.set_minor_locator(seclocator)
    axes[0].xaxis.set_minor_formatter(minorFmt)
    plt.setp(axes[0].xaxis.get_minorticklabels(), rotation=90 )

    # other codes
    # save fig as a picture

The x axis ticks of above code will get me:

enter image description here

How do I tell the minor locator to align with the major locator?
How do I tell the locators which timestamp to start ticking at?

what I have tried:
set_xlim doesn't do the trick
seclocator.tick_values(datetime_dummy, datetime_dummy1) doesn't do anything


Solution

  • Instead of using the interval keyword parameter, use bysecond and byminute to specify exactly which seconds and minutes you with to mark. The bysecond and byminute parameters are used to construct a dateutil rrule. The rrule generates datetimes which match certain specified patterns (or, one might say, "rules").

    For example, bysecond=[20, 40] limits the datetimes to those whose seconds equal 20 or 40. Thus, below, the minor tick marks only appear for datetimes whose soconds equal 20 or 40.

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.dates as matdates
    
    N = 100
    
    fig, ax = plt.subplots()
    x = np.arange(N).astype('<i8').view('M8[s]').tolist()
    y = (np.random.random(N)-0.5).cumsum()
    ax.plot(x, y)
    
    
    seclocator = matdates.SecondLocator(bysecond=[20, 40]) 
    minlocator = matdates.MinuteLocator(byminute=range(60))  # range(60) is the default
    
    seclocator.MAXTICKS  = 40000
    minlocator.MAXTICKS  = 40000
    
    majorFmt = matdates.DateFormatter('%Y-%m-%d, %H:%M:%S')  
    minorFmt = matdates.DateFormatter('%H:%M:%S')  
    
    ax.xaxis.set_major_locator(minlocator)
    ax.xaxis.set_major_formatter(majorFmt)
    plt.setp(ax.xaxis.get_majorticklabels(), rotation=90)
    
    ax.xaxis.set_minor_locator(seclocator)
    ax.xaxis.set_minor_formatter(minorFmt)
    plt.setp(ax.xaxis.get_minorticklabels(), rotation=90)
    
    plt.subplots_adjust(bottom=0.5)
    plt.show()
    

    enter image description here