{"spec_id":"phase-diagram","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nphase-diagram: Phase Diagram (State Space Plot)\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-05-14\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    element_line,\n    element_rect,\n    element_text,\n    geom_hline,\n    geom_path,\n    geom_point,\n    geom_vline,\n    ggplot,\n    ggsave,\n    labs,\n    scale_color_cmap,\n    theme,\n    theme_minimal,\n)\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\nBRAND = \"#009E73\"  # Okabe-Ito position 1\n\n# Data: Damped harmonic oscillator (spiral trajectory converging to equilibrium)\nnp.random.seed(42)\n\n# System parameters\nomega = 2 * np.pi  # Natural frequency\ngamma = 0.15  # Damping coefficient\n\n# Time array for smooth trajectory\nt = np.linspace(0, 8, 800)\n\n# Solution for damped harmonic oscillator: x = A * exp(-gamma*t) * cos(omega*t)\nA = 2.0  # Initial amplitude\nx = A * np.exp(-gamma * t) * np.cos(omega * t)\ndx_dt = A * np.exp(-gamma * t) * (-gamma * np.cos(omega * t) - omega * np.sin(omega * t))\n\n# Create DataFrame with time for color gradient\ndf = pd.DataFrame({\"x\": x, \"dx_dt\": dx_dt, \"t\": t})\n\n# Theme-adaptive chrome\nanyplot_theme = theme(\n    plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_grid_major=element_line(color=INK, size=0.3, alpha=0.10),\n    panel_grid_minor=element_line(color=INK, size=0.2, alpha=0.05),\n    panel_border=element_rect(color=INK_SOFT, fill=None, size=0.6),\n    axis_title=element_text(color=INK, size=20),\n    axis_text=element_text(color=INK_SOFT, size=16),\n    axis_line=element_line(color=INK_SOFT, size=0.5),\n    plot_title=element_text(color=INK, size=24),\n    legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n    legend_text=element_text(color=INK_SOFT, size=16),\n    legend_title=element_text(color=INK, size=16),\n    figure_size=(16, 9),\n)\n\n# Create phase diagram\nplot = (\n    ggplot(df, aes(x=\"x\", y=\"dx_dt\", color=\"t\"))\n    + geom_path(size=1.5, alpha=0.9)\n    + geom_point(data=df.iloc[[0]], size=5, color=BRAND, show_legend=False)  # Start point\n    + geom_point(data=df.iloc[[-1]], size=5, color=INK_SOFT, shape=\"s\", show_legend=False)  # End point\n    + geom_hline(yintercept=0, linetype=\"dashed\", color=INK_MUTED, alpha=0.5, size=0.5)\n    + geom_vline(xintercept=0, linetype=\"dashed\", color=INK_MUTED, alpha=0.5, size=0.5)\n    + scale_color_cmap(cmap_name=\"viridis\", name=\"Time (s)\")\n    + labs(x=\"Position x\", y=\"Velocity dx/dt\", title=\"phase-diagram · plotnine · anyplot.ai\")\n    + theme_minimal()\n    + anyplot_theme\n)\n\n# Save\nggsave(plot, f\"plot-{THEME}.png\", dpi=300, verbose=False)\n"}