dapper.mods.QG.illust_obs
Stream function and observation time series for QG (quasi-geostrophic) model.
1"""Stream function and observation time series for QG (quasi-geostrophic) model.""" 2 3if __name__ == "__main__": # dont run if pdoc (sample may not be avail/generate-able) 4 import numpy as np 5 from matplotlib import pyplot as plt 6 7 import dapper as dpr 8 from dapper.mods.QG.demo import show 9 from dapper.mods.QG.sakov2008 import HMM, obs_inds 10 from dapper.tools.progressbar import progbar 11 12 # Load (or generate) time-series data of a simulated state AND obs. 13 # (Alternative: re-use sample of QG/__init__.py and observe it) 14 fname = dpr.rc.dirs.data / "QG-ts.npz" 15 try: 16 with np.load(fname) as data: 17 xx = data["xx"][1:] 18 yy = data["yy"] 19 except FileNotFoundError: 20 xx, yy = HMM.simulate() 21 np.savez(fname, xx=xx, yy=yy) 22 23 # Insert obs on the same "grid" as the state vector 24 # Allocate the storage on the parent state dimension 25 yy_xx = np.full_like(xx, np.NaN) 26 for _k, ko, t, _dt in progbar(HMM.tseq.ticker, "Truth & Obs"): 27 if ko is not None: 28 indx = obs_inds(t) 29 yy_xx[ko, indx] = yy[ko, :] 30 31 # Create figure 32 fig, (ax1, ax2) = plt.subplots(ncols=2, sharex=True, sharey=True, figsize=(12, 6)) 33 for ax in (ax1, ax2): 34 ax.set_aspect("equal", "box") 35 ax1.set_title(r"Stream function: $\psi$") 36 ax2.set_title(r"Noisy observations: $\mathcal{H}(\psi) + \epsilon$") 37 38 # Define plot updating functions 39 setter1 = show(xx[0], psi=True, ax=ax1) 40 setter2 = show(yy_xx[0], psi=True, ax=ax2) 41 42 # Create double iterable for the animation 43 ts = zip(xx, yy_xx) 44 45 # Animate 46 for k, (xx, yy_xx) in progbar(list(enumerate(ts)), "Animating"): 47 if k % 2 == 0: 48 fig.suptitle("k: " + str(k)) 49 setter1(xx) 50 setter2(yy_xx) 51 plt.pause(0.01)