{"spec_id":"subplot-mosaic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nsubplot-mosaic: Mosaic Subplot Layout with Varying Sizes\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-14\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\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# Okabe-Ito palette\nBRAND = \"#009E73\"  # Position 1 - always first series\nOI_2 = \"#C475FD\"\nOI_3 = \"#4467A3\"\nOI_4 = \"#BD8233\"\n\n# Data\nnp.random.seed(42)\n\n# Time series data for main overview chart\ndates = np.arange(100)\nsales = np.cumsum(np.random.randn(100) * 5 + 2) + 500\n\n# Category data for bar chart\ncategories = [\"Product A\", \"Product B\", \"Product C\", \"Product D\"]\nvalues = [85, 120, 95, 110]\n\n# Scatter data for correlation plot\nx_scatter = np.random.normal(50, 15, 80)\ny_scatter = x_scatter * 0.8 + np.random.normal(0, 10, 80)\n\n# Histogram data\nmeasurements = np.random.normal(100, 20, 200)\n\n# Metric values for small panels\nmetrics = {\"Growth\": 12.5, \"Conversion\": 3.2, \"Retention\": 87.4}\n\n# Create mosaic layout: \"AAB;AAB;CDE\" pattern\n# A = large overview (spans 2 rows, 2 cols), B = bar chart (right side, 2 rows)\n# C, D, E = three small panels at bottom\nmosaic = \"\"\"\nAAB\nAAB\nCDE\n\"\"\"\n\nfig, axes = plt.subplot_mosaic(mosaic, figsize=(16, 9), facecolor=PAGE_BG)\nfig.patch.set_facecolor(PAGE_BG)\n\n# A: Main time series overview\naxes[\"A\"].set_facecolor(PAGE_BG)\naxes[\"A\"].plot(dates, sales, linewidth=3, color=BRAND)\naxes[\"A\"].fill_between(dates, sales.min(), sales, alpha=0.2, color=BRAND)\naxes[\"A\"].set_xlabel(\"Day\", fontsize=20, color=INK)\naxes[\"A\"].set_ylabel(\"Cumulative Sales ($)\", fontsize=20, color=INK)\naxes[\"A\"].set_title(\"Sales Overview\", fontsize=22, color=INK, fontweight=\"medium\")\naxes[\"A\"].tick_params(axis=\"both\", labelsize=16, colors=INK_SOFT)\nfor spine in (\"top\", \"right\"):\n    axes[\"A\"].spines[spine].set_visible(False)\nfor spine in (\"left\", \"bottom\"):\n    axes[\"A\"].spines[spine].set_color(INK_SOFT)\naxes[\"A\"].yaxis.grid(True, alpha=0.10, color=INK_SOFT, linewidth=0.8)\n\n# B: Bar chart for categories\naxes[\"B\"].set_facecolor(PAGE_BG)\nbars = axes[\"B\"].barh(categories, values, color=BRAND, edgecolor=INK_SOFT, linewidth=1.5)\naxes[\"B\"].set_xlabel(\"Units Sold\", fontsize=20, color=INK)\naxes[\"B\"].set_title(\"Product Performance\", fontsize=22, color=INK, fontweight=\"medium\")\naxes[\"B\"].tick_params(axis=\"both\", labelsize=16, colors=INK_SOFT)\nfor spine in (\"top\", \"right\"):\n    axes[\"B\"].spines[spine].set_visible(False)\nfor spine in (\"left\", \"bottom\"):\n    axes[\"B\"].spines[spine].set_color(INK_SOFT)\naxes[\"B\"].xaxis.grid(True, alpha=0.10, color=INK_SOFT, linewidth=0.8)\n# Add value labels\nfor bar, val in zip(bars, values, strict=True):\n    axes[\"B\"].text(val + 2, bar.get_y() + bar.get_height() / 2, str(val), va=\"center\", fontsize=14, color=INK)\n\n# C: Scatter plot\naxes[\"C\"].set_facecolor(PAGE_BG)\naxes[\"C\"].scatter(x_scatter, y_scatter, s=150, alpha=0.7, color=OI_2, edgecolors=PAGE_BG, linewidth=1)\naxes[\"C\"].set_xlabel(\"Feature X\", fontsize=18, color=INK)\naxes[\"C\"].set_ylabel(\"Feature Y\", fontsize=18, color=INK)\naxes[\"C\"].set_title(\"Correlation\", fontsize=20, color=INK, fontweight=\"medium\")\naxes[\"C\"].tick_params(axis=\"both\", labelsize=14, colors=INK_SOFT)\nfor spine in (\"top\", \"right\"):\n    axes[\"C\"].spines[spine].set_visible(False)\nfor spine in (\"left\", \"bottom\"):\n    axes[\"C\"].spines[spine].set_color(INK_SOFT)\naxes[\"C\"].grid(True, alpha=0.10, color=INK_SOFT, linewidth=0.8)\n\n# D: Histogram\naxes[\"D\"].set_facecolor(PAGE_BG)\naxes[\"D\"].hist(measurements, bins=20, color=OI_3, edgecolor=PAGE_BG, linewidth=1, alpha=0.8)\naxes[\"D\"].set_xlabel(\"Value\", fontsize=18, color=INK)\naxes[\"D\"].set_ylabel(\"Frequency\", fontsize=18, color=INK)\naxes[\"D\"].set_title(\"Distribution\", fontsize=20, color=INK, fontweight=\"medium\")\naxes[\"D\"].tick_params(axis=\"both\", labelsize=14, colors=INK_SOFT)\nfor spine in (\"top\", \"right\"):\n    axes[\"D\"].spines[spine].set_visible(False)\nfor spine in (\"left\", \"bottom\"):\n    axes[\"D\"].spines[spine].set_color(INK_SOFT)\naxes[\"D\"].yaxis.grid(True, alpha=0.10, color=INK_SOFT, linewidth=0.8)\n\n# E: Metrics display\naxes[\"E\"].set_facecolor(PAGE_BG)\naxes[\"E\"].set_xlim(0, 1)\naxes[\"E\"].set_ylim(0, 1)\naxes[\"E\"].axis(\"off\")\naxes[\"E\"].set_title(\"Key Metrics\", fontsize=20, color=INK, fontweight=\"medium\", pad=20)\ny_positions = [0.75, 0.45, 0.15]\ncolors = [BRAND, OI_2, OI_3]\nfor (name, value), y_pos, color in zip(metrics.items(), y_positions, colors, strict=True):\n    axes[\"E\"].text(0.5, y_pos, name, ha=\"center\", va=\"center\", fontsize=16, color=INK, fontweight=\"medium\")\n    axes[\"E\"].text(0.5, y_pos - 0.12, f\"{value}%\", ha=\"center\", va=\"center\", fontsize=24, color=color)\n# Add box around metrics\nrect = plt.Rectangle((0.05, 0.02), 0.9, 0.96, fill=False, edgecolor=INK_SOFT, linewidth=1.5)\naxes[\"E\"].add_patch(rect)\n\n# Main title\nfig.suptitle(\"subplot-mosaic · matplotlib · anyplot.ai\", fontsize=26, fontweight=\"medium\", color=INK, y=0.98)\n\nplt.tight_layout(rect=[0, 0, 1, 0.95])\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}