|
| 1 | +"""pyplots.ai |
| 2 | +scatter-lag: Lag Plot for Time Series Autocorrelation Diagnosis |
| 3 | +Library: seaborn | Python 3.13 |
| 4 | +Quality: pending | Created: 2026-04-12 |
| 5 | +""" |
| 6 | + |
| 7 | +import matplotlib.pyplot as plt |
| 8 | +import numpy as np |
| 9 | +import pandas as pd |
| 10 | +import seaborn as sns |
| 11 | + |
| 12 | + |
| 13 | +# Data - synthetic AR(1) process with strong positive autocorrelation |
| 14 | +np.random.seed(42) |
| 15 | +n = 500 |
| 16 | +phi = 0.85 |
| 17 | +noise = np.random.normal(0, 1, n) |
| 18 | + |
| 19 | +values = np.zeros(n) |
| 20 | +values[0] = noise[0] |
| 21 | +for t in range(1, n): |
| 22 | + values[t] = phi * values[t - 1] + noise[t] |
| 23 | + |
| 24 | +# Lag plot data (lag = 1) |
| 25 | +lag = 1 |
| 26 | +y_t = values[:-lag] |
| 27 | +y_t_lag = values[lag:] |
| 28 | +time_index = np.arange(len(y_t)) |
| 29 | + |
| 30 | +df = pd.DataFrame({"y(t)": y_t, "y(t + 1)": y_t_lag, "Time Index": time_index}) |
| 31 | + |
| 32 | +r = np.corrcoef(y_t, y_t_lag)[0, 1] |
| 33 | + |
| 34 | +# Plot |
| 35 | +sns.set_theme( |
| 36 | + style="ticks", |
| 37 | + context="talk", |
| 38 | + font_scale=1.1, |
| 39 | + rc={"font.family": "sans-serif", "axes.edgecolor": "#888888", "axes.linewidth": 0.8}, |
| 40 | +) |
| 41 | + |
| 42 | +fig, ax = plt.subplots(figsize=(16, 9)) |
| 43 | + |
| 44 | +scatter = ax.scatter( |
| 45 | + y_t, y_t_lag, c=time_index, cmap="viridis", s=70, alpha=0.65, edgecolors="white", linewidths=0.4, zorder=3 |
| 46 | +) |
| 47 | + |
| 48 | +# Diagonal reference line (y = x) |
| 49 | +data_min = min(y_t.min(), y_t_lag.min()) |
| 50 | +data_max = max(y_t.max(), y_t_lag.max()) |
| 51 | +margin = (data_max - data_min) * 0.05 |
| 52 | +ax.plot( |
| 53 | + [data_min - margin, data_max + margin], |
| 54 | + [data_min - margin, data_max + margin], |
| 55 | + color="#c44e52", |
| 56 | + linewidth=2, |
| 57 | + linestyle="--", |
| 58 | + alpha=0.6, |
| 59 | + zorder=2, |
| 60 | +) |
| 61 | + |
| 62 | +# Colorbar for temporal structure |
| 63 | +cbar = plt.colorbar(scatter, ax=ax, pad=0.02, aspect=30) |
| 64 | +cbar.set_label("Time Index", fontsize=18, color="#444444") |
| 65 | +cbar.ax.tick_params(labelsize=14) |
| 66 | + |
| 67 | +# Correlation coefficient |
| 68 | +ax.annotate( |
| 69 | + f"r = {r:.2f}", |
| 70 | + xy=(0.03, 0.96), |
| 71 | + xycoords="axes fraction", |
| 72 | + fontsize=18, |
| 73 | + fontweight="bold", |
| 74 | + color="#444444", |
| 75 | + ha="left", |
| 76 | + va="top", |
| 77 | + bbox={"boxstyle": "round,pad=0.4", "facecolor": "white", "edgecolor": "#cccccc", "alpha": 0.9}, |
| 78 | +) |
| 79 | + |
| 80 | +# Style |
| 81 | +ax.set_title( |
| 82 | + "AR(1) Autocorrelation · scatter-lag · seaborn · pyplots.ai", |
| 83 | + fontsize=24, |
| 84 | + fontweight="medium", |
| 85 | + color="#333333", |
| 86 | + pad=16, |
| 87 | +) |
| 88 | +ax.set_xlabel("y(t)", fontsize=20, color="#444444") |
| 89 | +ax.set_ylabel("y(t + 1)", fontsize=20, color="#444444") |
| 90 | +ax.tick_params(axis="both", labelsize=16, colors="#555555") |
| 91 | +ax.grid(True, alpha=0.15, linewidth=0.6) |
| 92 | +sns.despine(ax=ax) |
| 93 | + |
| 94 | +plt.tight_layout() |
| 95 | +plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
0 commit comments