{"spec_id":"parallel-basic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nparallel-basic: Basic Parallel Coordinates Plot\nLibrary: matplotlib 3.11.0 | Python 3.13.14\nQuality: 88/100 | Updated: 2026-07-24\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom matplotlib.collections import LineCollection\n\n\n# Theme tokens (see prompts/default-style-guide.md \"Background\" + \"Theme-adaptive Chrome\")\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\"\n\n# Imprint palette — 8 hues, theme-independent, hybrid-v3 sort. First 3 positions\n# used in canonical order for the 3 species (no semantic color cue applies here).\nIMPRINT_PALETTE = [\"#009E73\", \"#C475FD\", \"#4467A3\"]\n\n# Data - Iris dataset for multivariate demonstration (embedded for reproducibility)\nnp.random.seed(42)\n\n# Create Iris-like dataset with realistic measurements\ndata = {\n    \"sepal_length\": np.concatenate(\n        [\n            np.random.normal(5.0, 0.35, 50),  # Setosa\n            np.random.normal(5.9, 0.52, 50),  # Versicolor\n            np.random.normal(6.6, 0.64, 50),  # Virginica\n        ]\n    ),\n    \"sepal_width\": np.concatenate(\n        [\n            np.random.normal(3.4, 0.38, 50),  # Setosa\n            np.random.normal(2.8, 0.31, 50),  # Versicolor\n            np.random.normal(3.0, 0.32, 50),  # Virginica\n        ]\n    ),\n    \"petal_length\": np.concatenate(\n        [\n            np.random.normal(1.5, 0.17, 50),  # Setosa\n            np.random.normal(4.3, 0.47, 50),  # Versicolor\n            np.random.normal(5.5, 0.55, 50),  # Virginica\n        ]\n    ),\n    \"petal_width\": np.concatenate(\n        [\n            np.random.normal(0.2, 0.11, 50),  # Setosa\n            np.random.normal(1.3, 0.20, 50),  # Versicolor\n            np.random.normal(2.0, 0.27, 50),  # Virginica\n        ]\n    ),\n    \"species\": [\"setosa\"] * 50 + [\"versicolor\"] * 50 + [\"virginica\"] * 50,\n}\ndf = pd.DataFrame(data)\n\n# Ensure realistic bounds\ndf[\"sepal_length\"] = df[\"sepal_length\"].clip(4.3, 7.9)\ndf[\"sepal_width\"] = df[\"sepal_width\"].clip(2.0, 4.4)\ndf[\"petal_length\"] = df[\"petal_length\"].clip(1.0, 6.9)\ndf[\"petal_width\"] = df[\"petal_width\"].clip(0.1, 2.5)\n\n# Define numeric columns and normalize to [0, 1] for fair comparison\nnumeric_cols = [\"sepal_length\", \"sepal_width\", \"petal_length\", \"petal_width\"]\ndf_norm = df.copy()\nfor col in numeric_cols:\n    min_val = df[col].min()\n    max_val = df[col].max()\n    df_norm[col] = (df[col] - min_val) / (max_val - min_val)\n\n# Plot — see default-style-guide.md \"Visual Sizing Defaults\" for canvas + sizing values\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\ncolors = {\"setosa\": IMPRINT_PALETTE[0], \"versicolor\": IMPRINT_PALETTE[1], \"virginica\": IMPRINT_PALETTE[2]}\n\n# Vertical reference line at each dimension's axis position - anchors the\n# \"each variable is a vertical axis\" metaphor that parallel coordinates rely on\nx = np.arange(len(numeric_cols))\nfor xi in x:\n    ax.axvline(xi, color=INK_SOFT, alpha=0.3, linewidth=0.8, zorder=0)\n\n# Plot parallel coordinates - vectorized via LineCollection instead of a per-row loop\nsegments = np.stack([np.tile(x, (len(df_norm), 1)), df_norm[numeric_cols].to_numpy()], axis=2)\nline_colors = df_norm[\"species\"].map(colors).to_numpy()\nlc = LineCollection(segments, colors=line_colors, alpha=0.4, linewidths=2, zorder=2)\nax.add_collection(lc)\nax.set_xlim(x.min() - 0.15, x.max() + 0.15)\n\n# Axis labels with original scale ranges\nax.set_xticks(x)\nlabels = [\n    f\"Sepal Length\\n({df['sepal_length'].min():.1f}-{df['sepal_length'].max():.1f} cm)\",\n    f\"Sepal Width\\n({df['sepal_width'].min():.1f}-{df['sepal_width'].max():.1f} cm)\",\n    f\"Petal Length\\n({df['petal_length'].min():.1f}-{df['petal_length'].max():.1f} cm)\",\n    f\"Petal Width\\n({df['petal_width'].min():.1f}-{df['petal_width'].max():.1f} cm)\",\n]\nax.set_xticklabels(labels, fontsize=8, color=INK_SOFT)\nax.set_ylabel(\"Normalized Value\", fontsize=10, color=INK)\nax.set_title(\"parallel-basic · python · matplotlib · anyplot.ai\", fontsize=12, fontweight=\"medium\", color=INK)\nax.tick_params(axis=\"y\", labelsize=8, colors=INK_SOFT)\n\n# Add legend for species\nlegend_handles = [\n    plt.Line2D([0], [0], color=colors[\"setosa\"], linewidth=3, label=\"Setosa\"),\n    plt.Line2D([0], [0], color=colors[\"versicolor\"], linewidth=3, label=\"Versicolor\"),\n    plt.Line2D([0], [0], color=colors[\"virginica\"], linewidth=3, label=\"Virginica\"),\n]\nleg = ax.legend(handles=legend_handles, fontsize=8, loc=\"upper right\")\nleg.get_frame().set_facecolor(ELEVATED_BG)\nleg.get_frame().set_edgecolor(INK_SOFT)\nplt.setp(leg.get_texts(), color=INK_SOFT)\n\n# Styling\nax.set_ylim(-0.05, 1.05)\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor spine in (\"left\", \"bottom\"):\n    ax.spines[spine].set_color(INK_SOFT)\n\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)  # no bbox_inches='tight'\n"}