22

When I plot datapoints vs time, spanning over 2 days, and I set a datelocator for 0 and 30 minutes. A major tick for each half hour, matplotlib throws an error. Consider this example:

from datetime import datetime
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

datapoints = 3600*24*2   #2 days, 1 datapoint/second
data = range(datapoints)  #anydata
timestamps = [ datetime.fromtimestamp(t) for t in range(datapoints) ]

fig = plt.figure()
ax = fig.add_subplot(1,1,1)   
ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0,30]))

plt.plot(timestamps,data)
plt.show()

Then I get the following error:

RuntimeError: RRuleLocator estimated to generate 2879 ticks from 1970-01-01 01:00:00+00:00 to 1970-01-03 00:59:59+00:00: exceeds Locator.MAXTICKS * 2 (2000)

2879 ticks is exactly the amount of minutes in that timespan, meaning the estimate is based on 1 tick every minute. However the locator should yield 1 tick every 30 minutes (2 ticks per hour in 48 hour = 96 ticks). Why is the estimate and the real value so far from eachother?

A workaround would be to raise the MAXTICKS value:

locator = mdates.MinuteLocator(byminute=[0,30])
locator.MAXTICKS = 1500
ax.xaxis.set_major_locator(locator)

That works and the graph nicely shows. However that should not be needed right? Why is this error occuring in the first place? Am I using the datelocator wronly?

5
  • From a very brief inspection of the relevant source I would conclude that the DateLocators do account for the interval settings but not for the ones set by the byminute, byseconds, etc. I guess you might say that this is a bug. Lets see if @tcaswell can confirm Commented Jun 26, 2015 at 12:31
  • I think there is an outstanding issue about this on github. Commented Jun 26, 2015 at 16:55
  • Oh ok thanks, I checked now on github and couldn't find a relevant issue. Let me know if it helps if I add anything to the existing issue (url?) or if I add the issue on github. Commented Jun 28, 2015 at 19:41
  • I am also having this problem, good to see it is not (our) code's fault. Commented Sep 15, 2015 at 15:39
  • @tcaswell and others: Anyone had more luck here? I am also running into the same problem with the latest versions. Commented Mar 24, 2016 at 15:17

2 Answers 2

4

The real issue is that RRuleLocator assumes that the underlying rrule instance's interval variable will have been updated when byminute is set and interval isn't passed in on initialization (it defaults to 1). In fact, interval is completely ignored in rrule (with some small exceptions w.r.t. if filtered is set or not) when byxxx (hour/minute/second etc) is set!

Instead of overriding MAXTICKS, its better just to change your code to include the interval on the MinuteLocator to be 30 as well. This won't change how the final image is drawn as per above (unless you are using filtered).

ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0,30], interval=30))

Granted that while this is just a workaround as well, the estimation check in RRuleLocator's tick_values can be cleaned up to include what is set in the byxxx variables (although that could get messy).

Sign up to request clarification or add additional context in comments.

Comments

2

It seems your X axis had too many tick marks for the program to handle.

Try changing

    ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0,30]))

to

    ax.xaxis.set_major_locator(mdates.HourLocator(byhour=[0,1]))

The default maximum number of ticks is 2000 that is locator.MAXTICKS * 2.
Working in minutes you had 2879 ticks That at 1440 minutes per day for two days plus a buffer of 79 ticks.

Changing your x axis to hours gives 48 hours plus the buffer ticks which are well under the 2000 tick limit on the x axis.

Changing the default MAXTICKS to 1500 could work, but it defeats the intended protection.

At this time there is no option for a 30 minute tick mark.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.