のバグが原因でしたAutoDateLocator
。このバグはまだイシュー トラッカーに報告されていないようです。
あまりにも多くのラベルと目盛りがプロットされているため、奇妙に見えます。
日付を含むデータをプロットする場合、デフォルトでは、matplotlib はmatplotlib.dates.AutoDateLocator
メジャー ロケーターとして使用します。つまり、AutoDateLocator
ティック間隔とティック位置を決定するために使用されます。
データ シーケンスが で与えられるとし[datetime(2013, 1, 1), datetime(2013, 5, 18)]
ます。
タイム デルタは 4 か月と 17 日です。月の差分は 4 で、日の差分は 4*31+17=141 です。
matplotlib docsによると:
class matplotlib.dates.AutoDateLocator(tz=None, minticks=5, maxticks=None, interval_multiples=False)
minticks は必要なティックの最小数で、ティックのタイプ (年次、月次など) を選択するために使用されます。
maxticks は、必要なティックの最大数であり、ティック間の任意の間隔 (1 回おき、3 回おきなど) を制御します。本当にきめの細かい制御のために、これは個々の rrule 頻度定数 (YEARLY、MONTHLY など) を独自の最大ティック数にマッピングするディクショナリにすることができます。これを使用して、クラス:AutoDateFormatter で選択された形式に適切なティック数を維持できます。このディクショナリで指定されていない頻度には、デフォルト値が与えられます。
AutoDateLocator には、ティックの頻度 (dateutil.rrule の定数) とそのティックに許可されている倍数をマップする間隔辞書があります。デフォルトは次のようになります。
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]
}
間隔は、ティックの頻度に適した倍数を指定するために使用されます。たとえば、毎日の目盛りには 7 日ごとが適切ですが、分/秒の場合は 15 または 30 が適切です。次のようにして、この辞書をカスタマイズできます。
月の差分は 4 で 5 未満であり、日の差分は 141 で 5 未満ではないため、ティックのタイプは日単位になります。
ティックのタイプを解決した後AutoDateLocator
、間隔ディクショナリと maxticks ディクショナリを使用してティック間隔を決定します。
maxticks
がの場合None
、AutoDateLocator
デフォルトの maxticks ディクショナリを使用します。ドキュメントには、デフォルトのインターバル ディクショナリが示されていますが、デフォルトの maxticks ディクショナリがどのように見えるかは示されていません。dates.py
で見つけることができます。
self.maxticks = {YEARLY : 16, MONTHLY : 12, DAILY : 11, HOURLY : 16,
MINUTELY : 11, SECONDLY : 11}
ティック間隔を決定するアルゴリズムは次のとおりです。
# 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
カチカチの種類はDAILY
今です。141日のデルタもそうですfreq
。上記のコードは次と同等になりますDAILY
num
for interval in [1, 2, 3, 7, 14]:
if 141 <= interval * (11 - 1):
break
else:
interval = 1
141は大きすぎます。すべての毎日の間隔では、ティックが多すぎます。else
句が実行され、ティック間隔が 1 に設定されます。
これは、140 以上のラベルとティックがプロットされることを意味します。醜い x 軸が予想されます。
データ シーケンスが で与えられる場合、[datetime(2013, 1, 1), datetime(2013, 5, 17)]
1 日だけ短くなります。日のデルタは 140 です。次にAutoDateLocator
、ティック間隔として 14 を選択し、10 個のラベルのみがプロットされます。したがって、最初のグラフは問題なく表示されます。
maxticks
実際、制約が満たされない場合、matplotlib が間隔を 1 に設定する理由がわかりません。間隔が 1 の場合にのみ、ティック数がはるかに多くなります。私は最長の間隔を使用することを好みます。
結論:
範囲が 4 か月 18 日以上 5 か月未満の日付シーケンスを指定するとAutoDateLocator
、ティック間隔として 1 が選択されます。このような日付シーケンスをデフォルトの主要なロケーター、AutoDateLocator
つまり
解決策:
最も簡単な解決策は、毎日の maxticks を 12 に増やすことです。次に例を示します。
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()