{"spec_id":"line-parametric","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nline-parametric: Parametric Curve Plot\nLibrary: seaborn 0.13.2 | Python 3.13.14\nQuality: 86/100 | Updated: 2026-06-20\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport seaborn as sns\nfrom matplotlib.collections import LineCollection\nfrom matplotlib.colors import LinearSegmentedColormap\nfrom matplotlib.gridspec import GridSpec\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\"\n\n# Imprint sequential colormap: brand green → blue\nimprint_seq = LinearSegmentedColormap.from_list(\"imprint_seq\", [\"#009E73\", \"#4467A3\"])\n\n# Seaborn theme: warm background + theme-adaptive chrome\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.12,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Data — Lissajous: x = sin(3t), y = sin(2t), t ∈ [0, 2π]\nt_liss = np.linspace(0, 2 * np.pi, 1000)\nx_liss = np.sin(3 * t_liss)\ny_liss = np.sin(2 * t_liss)\n\n# Data — Archimedean spiral: x = t·cos(t), y = t·sin(t), t ∈ [0, 4π]\nt_spiral = np.linspace(0, 4 * np.pi, 1000)\nx_spiral = t_spiral * np.cos(t_spiral)\ny_spiral = t_spiral * np.sin(t_spiral)\n\n# Canvas: 3200 × 1800 px (landscape 16:9)\nfig = plt.figure(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\ngs = GridSpec(1, 2, figure=fig)\nax1 = fig.add_subplot(gs[0, 0])\nax2 = fig.add_subplot(gs[0, 1])\nax1.set_facecolor(PAGE_BG)\nax2.set_facecolor(PAGE_BG)\n\n# Lissajous — gradient line via inline LineCollection (Imprint sequential cmap)\npts_l = np.column_stack([x_liss, y_liss]).reshape(-1, 1, 2)\nsegs_l = np.concatenate([pts_l[:-1], pts_l[1:]], axis=1)\nlc1 = LineCollection(segs_l, cmap=imprint_seq, linewidths=3)\nlc1.set_array(t_liss[:-1])\nlc1.set_clim(0, 2 * np.pi)\nax1.add_collection(lc1)\nax1.autoscale()\n\n# Spiral — gradient line via inline LineCollection (Imprint sequential cmap)\npts_s = np.column_stack([x_spiral, y_spiral]).reshape(-1, 1, 2)\nsegs_s = np.concatenate([pts_s[:-1], pts_s[1:]], axis=1)\nlc2 = LineCollection(segs_s, cmap=imprint_seq, linewidths=3)\nlc2.set_array(t_spiral[:-1])\nlc2.set_clim(0, 4 * np.pi)\nax2.add_collection(lc2)\nax2.autoscale()\n\n# Lissajous is a closed curve (start = end = origin) — single marker\nsns.scatterplot(\n    x=[x_liss[0]],\n    y=[y_liss[0]],\n    s=150,\n    color=\"#009E73\",\n    marker=\"o\",\n    zorder=5,\n    label=\"t = 0 / 2π  (closed)\",\n    edgecolor=PAGE_BG,\n    linewidth=1.5,\n    ax=ax1,\n)\n\n# Spiral: distinct start (green) and end (red) markers\nsns.scatterplot(\n    x=[x_spiral[0]],\n    y=[y_spiral[0]],\n    s=150,\n    color=\"#009E73\",\n    marker=\"o\",\n    zorder=5,\n    label=\"Start  t = 0\",\n    edgecolor=PAGE_BG,\n    linewidth=1.5,\n    ax=ax2,\n)\nsns.scatterplot(\n    x=[x_spiral[-1]],\n    y=[y_spiral[-1]],\n    s=150,\n    color=\"#AE3030\",\n    marker=\"s\",\n    zorder=5,\n    label=\"End  t = 4π\",\n    edgecolor=PAGE_BG,\n    linewidth=1.5,\n    ax=ax2,\n)\n\n# Colorbars with π-symbol tick labels\ncb1 = fig.colorbar(lc1, ax=ax1, shrink=0.65, pad=0.04)\ncb1.set_label(\"Parameter t\", fontsize=8, color=INK)\ncb1.set_ticks([0, np.pi, 2 * np.pi])\ncb1.set_ticklabels([\"0\", \"π\", \"2π\"])\ncb1.ax.tick_params(labelsize=8, colors=INK_SOFT)\n\ncb2 = fig.colorbar(lc2, ax=ax2, shrink=0.65, pad=0.04)\ncb2.set_label(\"Parameter t\", fontsize=8, color=INK)\ncb2.set_ticks([0, 2 * np.pi, 4 * np.pi])\ncb2.set_ticklabels([\"0\", \"2π\", \"4π\"])\ncb2.ax.tick_params(labelsize=8, colors=INK_SOFT)\n\n# Panel styling via seaborn's despine + explicit chrome\nfor ax, panel_title, legend_loc in [\n    (ax1, \"Lissajous: x = sin(3t),  y = sin(2t)\", \"lower right\"),\n    (ax2, \"Spiral: x = t·cos(t),  y = t·sin(t)\", \"best\"),\n]:\n    ax.set_aspect(\"equal\")\n    ax.set_title(panel_title, fontsize=10, fontweight=\"medium\", color=INK)\n    ax.set_xlabel(\"x(t)\", fontsize=9, color=INK)\n    ax.set_ylabel(\"y(t)\", fontsize=9, color=INK)\n    ax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\n    ax.legend(fontsize=8, loc=legend_loc, framealpha=0.9, facecolor=ELEVATED_BG, edgecolor=INK_SOFT)\n    ax.grid(True, alpha=0.12, linewidth=0.5, color=INK)\n    sns.despine(ax=ax)\n\n# Frequency ratio annotation — data storytelling for Lissajous\nax1.text(\n    0.97,\n    0.03,\n    \"freq. ratio  3 : 2\",\n    transform=ax1.transAxes,\n    fontsize=7,\n    color=INK_MUTED,\n    ha=\"right\",\n    va=\"bottom\",\n    style=\"italic\",\n)\n\nfig.suptitle(\"line-parametric · python · seaborn · anyplot.ai\", fontsize=12, fontweight=\"medium\", color=INK, y=0.99)\nfig.subplots_adjust(left=0.07, right=0.95, top=0.90, bottom=0.10, wspace=0.45)\n\n# Save — exact 3200 × 1800 px; no bbox_inches=\"tight\" (would trim canvas)\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}