{"spec_id":"parallel-categories-basic","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nparallel-categories-basic: Basic Parallel Categories Plot\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 93/100 | Updated: 2026-05-13\n\"\"\"\n\nimport os\n\nimport plotly.graph_objects as go\nimport seaborn as sns\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 colors for categorical data\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\"]\n\n# Data - Titanic survival data with multiple categorical dimensions\ndf = sns.load_dataset(\"titanic\")\n\n# Prepare data: select key categorical variables\ndf = df[[\"class\", \"sex\", \"embarked\", \"survived\"]].dropna()\n\n# Map survived to readable labels\ndf[\"outcome\"] = df[\"survived\"].map({0: \"Did Not Survive\", 1: \"Survived\"})\n\n# Create dimension specifications for parallel categories\ndimensions = [\n    {\n        \"label\": \"Passenger Class\",\n        \"values\": df[\"class\"].astype(str),\n        \"categoryorder\": \"array\",\n        \"categoryarray\": [\"First\", \"Second\", \"Third\"],\n    },\n    {\n        \"label\": \"Sex\",\n        \"values\": df[\"sex\"].str.capitalize(),\n        \"categoryorder\": \"array\",\n        \"categoryarray\": [\"Female\", \"Male\"],\n    },\n    {\n        \"label\": \"Embarked\",\n        \"values\": df[\"embarked\"].map({\"C\": \"Cherbourg\", \"Q\": \"Queenstown\", \"S\": \"Southampton\"}),\n        \"categoryorder\": \"array\",\n        \"categoryarray\": [\"Cherbourg\", \"Queenstown\", \"Southampton\"],\n    },\n    {\n        \"label\": \"Outcome\",\n        \"values\": df[\"outcome\"],\n        \"categoryorder\": \"array\",\n        \"categoryarray\": [\"Survived\", \"Did Not Survive\"],\n    },\n]\n\n# Create color scale based on survival outcome (Okabe-Ito palette)\ncolor_values = df[\"survived\"].values\n\n# Create parallel categories plot\nfig = go.Figure(\n    go.Parcats(\n        dimensions=dimensions,\n        line={\"color\": color_values, \"colorscale\": [[0, IMPRINT[1]], [1, IMPRINT[0]]], \"shape\": \"hspline\"},\n        hoveron=\"color\",\n        hoverinfo=\"count+probability\",\n        arrangement=\"freeform\",\n    )\n)\n\n# Update layout for 4800x2700 canvas with theme-adaptive styling\nfig.update_layout(\n    title={\n        \"text\": \"parallel-categories-basic · plotly · anyplot.ai\",\n        \"font\": {\"size\": 28, \"color\": INK},\n        \"x\": 0.5,\n        \"xanchor\": \"center\",\n    },\n    font={\"size\": 18, \"color\": INK_SOFT},\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    margin={\"l\": 100, \"r\": 100, \"t\": 120, \"b\": 80},\n)\n\n# Save PNG and HTML with theme-suffixed filenames\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}