{"spec_id":"ridgeline-basic","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nridgeline-basic: Basic Ridgeline Plot\nLibrary: letsplot 4.11.0 | Python 3.13.14\nQuality: 92/100 | Updated: 2026-07-25\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import *\nfrom lets_plot.export import ggsave as export_ggsave\n\n\nLetsPlot.setup_html()\n\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\"\nRULE = \"rgba(26,26,23,0.2)\" if THEME == \"light\" else \"rgba(240,239,232,0.2)\"\n\n# Data - Monthly temperature distributions (realistic weather data)\nnp.random.seed(42)\n\nmonths = [\n    \"January\",\n    \"February\",\n    \"March\",\n    \"April\",\n    \"May\",\n    \"June\",\n    \"July\",\n    \"August\",\n    \"September\",\n    \"October\",\n    \"November\",\n    \"December\",\n]\n\n# Temperature parameters (mean, std) for each month - Northern hemisphere pattern\ntemp_params = {\n    \"January\": (2, 5),\n    \"February\": (4, 5),\n    \"March\": (8, 5),\n    \"April\": (13, 4),\n    \"May\": (17, 4),\n    \"June\": (21, 3),\n    \"July\": (24, 3),\n    \"August\": (23, 3),\n    \"September\": (19, 4),\n    \"October\": (14, 4),\n    \"November\": (8, 5),\n    \"December\": (4, 5),\n}\n\n# Generate temperature observations for each month\ndata = []\nfor month in months:\n    mean, std = temp_params[month]\n    temps = np.random.normal(mean, std, 150)\n    for t in temps:\n        data.append({\"Month\": month, \"Temperature\": t})\n\ndf = pd.DataFrame(data)\n\n# Convert month to categorical with correct order (reversed for ridgeline bottom-to-top)\ndf[\"Month\"] = pd.Categorical(df[\"Month\"], categories=months[::-1], ordered=True)\n\n# Imprint imprint_seq gradient (brand green -> blue), keyed by each month's mean\n# temperature rather than calendar order: single-polarity intensity encoding, per\n# the style guide's \"Continuous Data\" rule, so hue reads as a temperature story\n# (coldest months green, warmest months blue) instead of an arbitrary sequence.\n# Intentional exception to the 8-slot categorical palette: this chart type needs\n# all 12 groups visible at once, so small multiples (the 9+ series guidance) would\n# defeat the point of a ridgeline; every group still stays within the Imprint family.\nmeans = [temp_params[month][0] for month in months]\nmean_lo, mean_hi = min(means), max(means)\nmonth_colors = {\n    month: \"#{:02X}{:02X}{:02X}\".format(\n        *(\n            round(a + (b - a) * (temp_params[month][0] - mean_lo) / (mean_hi - mean_lo))\n            for a, b in zip((0x00, 0x9E, 0x73), (0x44, 0x67, 0xA3), strict=True)\n        )\n    )\n    for month in months\n}\n\nplot = (\n    ggplot(df, aes(x=\"Temperature\", y=\"Month\", fill=\"Month\"))\n    + geom_area_ridges(\n        scale=1.2,  # Overlap amount (>1 means overlap)\n        alpha=0.85,\n        size=1.0,  # Border thickness\n        color=PAGE_BG,  # Border matches page background for clean ridge separation\n    )\n    + scale_fill_manual(values=month_colors)\n    + labs(\n        x=\"Temperature (°C)\",\n        y=\"\",\n        title=\"Monthly Temperature Distribution · ridgeline-basic · python · letsplot · anyplot.ai\",\n    )\n    + theme_minimal()\n    + theme(\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        axis_title=element_text(size=12, color=INK),\n        axis_text_x=element_text(size=10, color=INK_SOFT),\n        axis_text_y=element_text(size=10, color=INK_SOFT),\n        axis_line=element_line(color=INK_SOFT),\n        plot_title=element_text(size=13, color=INK),\n        legend_position=\"none\",  # Y-axis labels are sufficient; fill encodes temperature intensity\n        panel_border=element_blank(),\n        panel_grid_major_y=element_blank(),\n        panel_grid_major_x=element_line(color=RULE, size=0.5),\n        panel_grid_minor=element_blank(),\n    )\n    + ggsize(800, 450)\n)\n\n# Save PNG (scale 4x for 3200x1800) and HTML\nexport_ggsave(plot, f\"plot-{THEME}.png\", path=\".\", scale=4)\nexport_ggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}