It is counted by an error in AutoDateLocator . It seems that this error has not yet been sent to problem tracking.
It looks weird just because there are too many shortcuts and ticks applied.
When building with data with default dates, matplotlib uses matplotlib.dates.AutoDateLocator as the main locator. Namely, AutoDateLocator used to determine tick intervals and tick locations.
Suppose a data sequence is given [datetime(2013, 1, 1), datetime(2013, 5, 18)] .
The delta time is 4 months and 17 days. The delta of the month is 4, and the delta of the day is 4 * 31 + 17 = 141.
According to matplotlib docs :
class matplotlib.dates.AutoDateLocator (tz = None, minticks = 5, maxticks = None, interval_multiples = False)
minticks is the minimum number of desired ticks that is used to select the type of tick (annually, monthly, etc.).
maxticks - the maximum number of desired ticks that controls any interval between ticks (ticking each other, every 3, etc.). For really fine-grained control, it can be a dictionary comparing individual rrule frequency constants (YEARS, MONTHLY, etc.) with their own maximum number of ticks. This can be used to ensure that the number of ticks matches the format selected in the class: AutoDateFormatter. Any frequency not specified in this dictionary has a default value.
AutoDateLocator has an interval dictionary that displays the tick frequency (constant from dateutil.rrule) and several ticks allowed for this. The default value is as follows:
self.intervald = { YEARLY : [1, 2, 4, 5, 10], MONTHLY : [1, 2, 3, 4, 6], DAILY : [1, 2, 3, 7, 14], HOURLY : [1, 2, 3, 4, 6, 12], MINUTELY: [1, 5, 10, 15, 30], SECONDLY: [1, 5, 10, 15, 30] }
Interval is used to indicate multiple values corresponding to the tick frequency. For example, every 7 days are reasonable for daily ticks, but within minutes / seconds 15 or 30 make sense. You can customize this dictionary by following these steps:
Since the delta of the month is 4, less than 5, and the delta of the day is 141, at least 5. The type of tick will be daily.
After determining the tick type, AutoDateLocator will use the interval dictionary and the maxticks dictionary to determine the tick interval.
When maxticks is None , AutoDateLocator uses its default maxticks dictionary. The documentation shows us the default interval dictionary and does not tell us what the default maxticks dictionary looks like.
We can find it in dates.py .
self.maxticks = {YEARLY : 16, MONTHLY : 12, DAILY : 11, HOURLY : 16, MINUTELY : 11, SECONDLY : 11}
Tick Interval Algorithm
# Find the first available interval that doesn't give too many ticks for interval in self.intervald[freq]: if num <= interval * (self.maxticks[freq] - 1): break else: # We went through the whole loop without breaking, default to 1 interval = 1
Now the tick type is DAILY . So freq is DAILY , and num is 141, the delta of the day. The above code will be equivalent
for interval in [1, 2, 3, 7, 14]: if 141 <= interval * (11 - 1): break else: interval = 1
141 is too large. All daily intervals will produce too many ticks. else will execute and the tick interval will be set to 1.
This means that stickers and ticks will be + ++. We can expect the ugly x axis.
If the data sequence is specified [datetime(2013, 1, 1), datetime(2013, 5, 17)] , one day less. the daily delta is 140. Then AutoDateLocator will select 14 as the tick interval and only 10 marks will be applied. So your first chart looks fine.
Actually I don't understand why matplotlib chooses to set the interval to 1 if the maxticks constraint cannot be met. This will only result in a significantly larger number of ticks if the interval is 1. I prefer to use the longest interval.
OUTPUT:
For any sequence of days whose range is greater than or equal to 4 months and 18 days, and less than 5 months, AutoDateLocator will select 1 as the tick interval. You will see some ugly behavior on the x-axis or y-axis when constructing such a date sequence with a default default locator, namely AutoDateLocator .
DECISION:
The easiest solution is to increase your daily macchiques to 12. For example:
import numpy as np import matplotlib.pyplot as plt from matplotlib.dates import DAILY from datetime import datetime ax = plt.subplot(111) plt.plot_date([datetime(2013, 1, 1), datetime(2013, 5, 31)], [datetime(2013, 1, 1), datetime(2013, 5, 10)]) loc = ax.xaxis.get_major_locator() loc.maxticks[DAILY] = 12 plt.show()