Closed tetsushiwahaha closed 1 year ago
おそらく,下記 2 点が混乱の原因かと推察します.
plt
オブジェクト内で座標情報を保持しているplt.pause()
が実行される度に,それまで plt
オブジェクトに渡された全ての軌道が再描画(update)されている以下,細かい説明です.
Matplotlib の plt.plot
では,与えた二次元配列を Line2D という独自クラスに置き換え,対応する axes
オブジェクトの lines
という配列(ArtistList)に格納しています.
そして,plt.pause(0.001)
のたびに配列 lines
が読まれ,描画がアップデートされています.
つまりは,視覚的には既存の軌道に新たな軌道が append されているようにしか見えないのですが,実際のプログラムは初期値から最新の状態までの軌道を plt.pause(0.001)
のたびに書き直しています.(置き換えている,の方が正確かもしれません.)
erase_old_traj
の実装では
current_axes = plt.gca()
number_of_plots = len(current_axes.lines)
if number_of_plots > cfg.max_plots:
for line in current_axes.lines[: -cfg.max_plots]:
line.remove()
となっていますが,current_axes.lines
が ArtistList
に対応していて,中身は
lines[0] = sol.y(0 -> 2*pi, tick=1e-2) # 629 個のデータ点列
lines[1] = sol.y(2*pi -> 4*pi, tick=1e-2) # 629 個のデータ点列
lines[2] = sol.y(4*pi -> 6*pi, tick=1e-2) # 629 個のデータ点列
....
という感じになっています.
実際のところは,
linewidth
だったりのスタイル情報も含まれますので,こんなに簡単ではありませんが^^; 詳細は Line2D にて.
cfg.max_plots
のデフォルト設定は 64 としていますので,len(lines)
が 65 以上の場合,新しい軌道 64 セット分(時刻 2*pi*n
においては sol.y(2*pi*(n-64) -> 2*pi*n)
)を除いて残りを処分する,という実装になっています.
なるほど,OpenGLもそんな感じの実装だったような気がしてきた… 無反省に描き続けるとメモリを消費する・redrawに時間が無駄に失われるのはかなわんので,不要なものをunlinkする機能は持っておいていただきたいが,この本としては過渡応答が不意に消えてしまうのはあまり望ましくないと思う.まぁ,消すまでのインターバルを長くすればいいのだとは思うが. それと,pause(0.001) は,ウエタがどっかの記述からパクったもので何も考えてはいないが,現時点の実装だと,cfg.running が Trueである限り回るループのたびに呼ばれる一瞬のポーズであって,0.001のたびredraw されるのではなく,この pause()が呼び出されるたびにredraw されるのでは? 0.001 ってすると何よ,という気もするが,イベント処理のタイムアウトかと思ってた.どうでしょう?
plt.pause() が実行される度に,それまで plt オブジェクトに渡された全ての軌道が再描画(update)されている
ああ,そのように書かれてますね.すいません,私が読み違えたか.
ま,リクエストとしては erase_old_traj()をメインから隠してほしい,ってとこです.
erase_old_traj()
は draw_traj()
に含めても問題ありませんので, a201a4e のコミットでそのように変更しておきました.
特に問題なければ Close しましょうかね?
ほい.ありがとうございました.
えーと,erase_old_traj()ってのがあるが,なんか先日の議論の中で初期値から軌道のすべての点を憶えてるから不要な分は消さないと,的な話の実装でしょうか?よくわかってないが,solve_ivp自体は1コールで与えたx_0を,tstart から tend まで積分してその軌道のリストを返すだけで,もう一度コールしても,x_0, tstartをセットし直せば,旧の軌道情報はパージされるんではないのですか?まぁ現在のdraw_traj()見る限り,後で消さないかんようなリストの追加コードはなさそうですが,たしかにerase_old_traj()読んだら初期値から徐々に消されたりして,なんで?という感じですが,どうなんでしょう?