web-dev-qa-db-ja.com

Matplotlib日付ティッカー-明らかな理由もなくLocator.MAXTICKSエラーを超えています

2日間にわたるデータポイントと時間の関係をプロットし、日付ロケーターを0分と30分に設定した場合。 30分ごとに大きな目盛りがあり、matplotlibはエラーをスローします。この例を考えてみましょう。

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()

次に、次のエラーが発生します。

RuntimeError:RRuleLocatorは、1970-01-01 01:00:00 + 00:00から1970-01-03 00:59:59 + 00:00まで2879ティックを生成すると推定されています:Locator.MAXTICKS * 2(2000)を超えています

2879ティックは、まさにその期間の分数です。つまり、見積もりは1分ごとに1ティックに基づいています。ただし、ロケーターは30分ごとに1ティックを生成する必要があります(48時間で1時間あたり2ティック= 96ティック)。なぜ見積もりと実際の値が互いに離れているのですか?

回避策は、MAXTICKS値を上げることです。

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

それは機能し、グラフはうまく表示されます。しかし、それは必要ないはずですよね?そもそもなぜこのエラーが発生するのですか? datelocator wronlyを使用していますか?

17
Sebastian

実際の問題は、RRuleLocatorは、byminuteが設定され、初期化時に間隔が渡されない場合(デフォルトは1)、基になるrruleインスタンスのinterval変数が更新されると想定することです。実際、byxxx(時間/分/秒など)が設定されている場合、rruleでは間隔が完全に無視されます(フィルターが設定されているかどうかにかかわらず、いくつかの小さな例外があります)。

MAXTICKSをオーバーライドする代わりに、MinuteLocatorの間隔も30になるようにコードを変更する方がよいでしょう。これにより、上記のように最終的な画像が描画される方法は変わりません(フィルターを使用している場合を除く)。

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

これも単なる回避策ですが、RRuleLocatorのtick_valuesの推定チェックをクリーンアップして、byxxx変数に設定されているものを含めることができます(ただし、面倒になる可能性があります)。

3
Alkora

X軸に目盛りが多すぎて、プログラムで処理できないようです。

変更してみてください

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

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

デフォルトの最大ティック数は2000、つまりlocator.MAXTICKS * 2です。
[。

X軸を時間に変更すると、48時間に加えて、x軸の2000ティック制限をはるかに下回るバッファーティックが得られます。

デフォルトのMAXTICKSを1500に変更しても機能する可能性がありますが、意図した保護が無効になります。

現時点では、30分の目盛りのオプションはありません。

0
Paco