{"spec_id":"andrews-curves","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nandrews-curves: Andrews Curves for Multivariate Data\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-15\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_line,\n    ggplot,\n    labs,\n    scale_color_manual,\n    theme,\n    theme_minimal,\n)\nfrom sklearn.datasets import load_iris\nfrom sklearn.preprocessing import StandardScaler\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Okabe-Ito palette (first series is always #009E73)\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\"]\n\n# Data\niris = load_iris()\nX = iris.data\ny = iris.target\nfeature_names = iris.feature_names\ntarget_names = iris.target_names\n\n# Normalize the data\nscaler = StandardScaler()\nX_normalized = scaler.fit_transform(X)\n\n# Generate t values for the curve\nt = np.linspace(-np.pi, np.pi, 100)\n\n# Create data for plotting with inlined Andrews curve transformation\nplot_data = []\nfor idx in range(len(X_normalized)):\n    row = X_normalized[idx]\n    n = len(row)\n    # Andrews curve Fourier transformation: x1/sqrt(2) + x2*sin(t) + x3*cos(t) + x4*sin(2t) + ...\n    curve_values = row[0] / np.sqrt(2)\n    for i in range(1, n):\n        if i % 2 == 1:\n            curve_values = curve_values + row[i] * np.sin((i // 2 + 1) * t)\n        else:\n            curve_values = curve_values + row[i] * np.cos((i // 2) * t)\n    species = target_names[y[idx]]\n    for t_val, curve_val in zip(t, curve_values, strict=True):\n        plot_data.append({\"t\": t_val, \"value\": curve_val, \"species\": species, \"observation\": idx})\n\ndf = pd.DataFrame(plot_data)\n\n# Theme-adaptive styling\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),\n    axis_title=element_text(size=20, color=INK),\n    axis_text=element_text(size=16, color=INK_SOFT),\n    axis_line=element_line(color=INK_SOFT),\n    plot_title=element_text(size=24, color=INK),\n    legend_text=element_text(size=16, color=INK_SOFT),\n    legend_title=element_text(size=18, color=INK),\n)\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"t\", y=\"value\", color=\"species\", group=\"observation\"))\n    + geom_line(alpha=0.4, size=0.8)\n    + labs(title=\"andrews-curves · plotnine · anyplot.ai\", x=\"t (radians)\", y=\"Andrews Curve Value\", color=\"Species\")\n    + scale_color_manual(values=IMPRINT)\n    + theme_minimal()\n    + anyplot_theme\n    + theme(figure_size=(16, 9))\n)\n\n# Save\nplot.save(f\"plot-{THEME}.png\", dpi=300, verbose=False)\n"}