{"spec_id":"subplot-mosaic","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nsubplot-mosaic: Mosaic Subplot Layout with Varying Sizes\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-14\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nimport plotly.graph_objects as go\nfrom plotly.subplots import make_subplots\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\"\nGRID = \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\"\n\n# Okabe-Ito palette\nIMPRINT = [\n    \"#009E73\",  # brand — first series\n    \"#C475FD\",\n    \"#4467A3\",\n    \"#BD8233\",\n    \"#AE3030\",\n    \"#2ABCCD\",\n    \"#954477\",\n]\n\n# Data\nnp.random.seed(42)\n\n# Time series data for the wide overview chart (A - spans top row)\ndates = pd.date_range(\"2024-01-01\", periods=120, freq=\"D\")\nrevenue = 50000 + np.cumsum(np.random.randn(120) * 1000) + np.arange(120) * 200\nrevenue = np.maximum(revenue, 30000)\n\n# Monthly breakdown for bar chart (B - top right)\nmonths = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\"]\nmonthly_sales = [42000, 48000, 51000, 46000, 58000, 62000]\n\n# Scatter data for distribution view (C - middle spanning)\nproduct_x = np.random.randn(100) * 15 + 50\nproduct_y = product_x * 0.7 + np.random.randn(100) * 10 + 20\n\n# Category comparison (D - middle right)\ncategories = [\"Electronics\", \"Clothing\", \"Food\", \"Books\", \"Sports\"]\ncat_values = [35, 28, 22, 15, 18]\n\n# Metric panel data (E, F, G - bottom row)\nmetric_1_history = np.random.rand(30) * 20 + 80\nmetric_2_history = np.random.rand(30) * 15 + 60\nmetric_3_history = np.random.rand(30) * 25 + 45\n\n# Create mosaic layout: \"AAB;CCD;EFG\"\n# Row 1: A spans 2 cols, B takes 1 col\n# Row 2: C spans 2 cols, D takes 1 col\n# Row 3: E, F, G each take 1 col\n\nfig = make_subplots(\n    rows=3,\n    cols=3,\n    specs=[[{\"colspan\": 2}, None, {}], [{\"colspan\": 2}, None, {}], [{}, {}, {}]],\n    row_heights=[0.45, 0.35, 0.30],\n    column_widths=[0.33, 0.33, 0.34],\n    subplot_titles=[\n        \"Revenue Trend (Overview)\",\n        \"Monthly Sales\",\n        \"Product Performance\",\n        \"Category Distribution\",\n        \"Efficiency\",\n        \"Quality Score\",\n        \"Response Time\",\n    ],\n    vertical_spacing=0.12,\n    horizontal_spacing=0.10,\n)\n\n# A: Revenue trend line (top spanning)\nfig.add_trace(\n    go.Scatter(\n        x=dates,\n        y=revenue,\n        mode=\"lines\",\n        line={\"color\": IMPRINT[0], \"width\": 4},\n        fill=\"tozeroy\",\n        fillcolor=f\"rgba({int(IMPRINT[0][1:3], 16)}, {int(IMPRINT[0][3:5], 16)}, {int(IMPRINT[0][5:7], 16)}, 0.2)\",\n        name=\"Revenue\",\n    ),\n    row=1,\n    col=1,\n)\n\n# B: Monthly sales bar (top right)\nfig.add_trace(go.Bar(x=months, y=monthly_sales, marker_color=IMPRINT[1], name=\"Monthly\"), row=1, col=3)\n\n# C: Product scatter (middle spanning) — INCREASED marker size\nfig.add_trace(\n    go.Scatter(\n        x=product_x,\n        y=product_y,\n        mode=\"markers\",\n        marker={\"size\": 16, \"color\": IMPRINT[0], \"opacity\": 0.8},\n        name=\"Products\",\n    ),\n    row=2,\n    col=1,\n)\n\n# D: Category horizontal bar (middle right)\nfig.add_trace(\n    go.Bar(\n        y=categories,\n        x=cat_values,\n        orientation=\"h\",\n        marker_color=[IMPRINT[0], IMPRINT[1], IMPRINT[2], IMPRINT[3], IMPRINT[4]],\n        name=\"Categories\",\n    ),\n    row=2,\n    col=3,\n)\n\n# E: Efficiency metric (bottom left)\nfig.add_trace(\n    go.Scatter(\n        x=list(range(30)),\n        y=metric_1_history,\n        mode=\"lines\",\n        line={\"color\": IMPRINT[0], \"width\": 3},\n        fill=\"tozeroy\",\n        fillcolor=f\"rgba({int(IMPRINT[0][1:3], 16)}, {int(IMPRINT[0][3:5], 16)}, {int(IMPRINT[0][5:7], 16)}, 0.25)\",\n        name=\"Efficiency\",\n    ),\n    row=3,\n    col=1,\n)\n\n# F: Quality score metric (bottom middle)\nfig.add_trace(\n    go.Scatter(\n        x=list(range(30)),\n        y=metric_2_history,\n        mode=\"lines\",\n        line={\"color\": IMPRINT[1], \"width\": 3},\n        fill=\"tozeroy\",\n        fillcolor=f\"rgba({int(IMPRINT[1][1:3], 16)}, {int(IMPRINT[1][3:5], 16)}, {int(IMPRINT[1][5:7], 16)}, 0.25)\",\n        name=\"Quality\",\n    ),\n    row=3,\n    col=2,\n)\n\n# G: Response time metric (bottom right)\nfig.add_trace(\n    go.Scatter(\n        x=list(range(30)),\n        y=metric_3_history,\n        mode=\"lines\",\n        line={\"color\": IMPRINT[2], \"width\": 3},\n        fill=\"tozeroy\",\n        fillcolor=f\"rgba({int(IMPRINT[2][1:3], 16)}, {int(IMPRINT[2][3:5], 16)}, {int(IMPRINT[2][5:7], 16)}, 0.25)\",\n        name=\"Response\",\n    ),\n    row=3,\n    col=3,\n)\n\n# Update layout with theme-adaptive colors\nfig.update_layout(\n    title={\n        \"text\": \"subplot-mosaic · plotly · anyplot.ai\",\n        \"font\": {\"size\": 28, \"color\": INK},\n        \"x\": 0.5,\n        \"xanchor\": \"center\",\n    },\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    font={\"color\": INK},\n    showlegend=False,\n    margin={\"l\": 100, \"r\": 80, \"t\": 140, \"b\": 80},\n    hovermode=\"closest\",\n)\n\n# Update axes with theme-adaptive colors\nfig.update_xaxes(\n    tickfont={\"size\": 18, \"color\": INK_SOFT},\n    title_font={\"size\": 22, \"color\": INK},\n    gridcolor=GRID,\n    linecolor=INK_SOFT,\n    zerolinecolor=INK_SOFT,\n)\n\nfig.update_yaxes(\n    tickfont={\"size\": 18, \"color\": INK_SOFT},\n    title_font={\"size\": 22, \"color\": INK},\n    gridcolor=GRID,\n    linecolor=INK_SOFT,\n    zerolinecolor=INK_SOFT,\n)\n\n# Axis labels\nfig.update_xaxes(title_text=\"Date\", row=1, col=1)\nfig.update_yaxes(title_text=\"Revenue ($)\", row=1, col=1)\nfig.update_xaxes(title_text=\"Month\", row=1, col=3)\nfig.update_yaxes(title_text=\"Sales ($)\", row=1, col=3)\nfig.update_xaxes(title_text=\"Feature X\", row=2, col=1)\nfig.update_yaxes(title_text=\"Feature Y\", row=2, col=1)\nfig.update_xaxes(title_text=\"Units Sold\", row=2, col=3)\nfig.update_xaxes(title_text=\"Days\", row=3, col=1)\nfig.update_yaxes(title_text=\"%\", row=3, col=1)\nfig.update_xaxes(title_text=\"Days\", row=3, col=2)\nfig.update_yaxes(title_text=\"Score\", row=3, col=2)\nfig.update_xaxes(title_text=\"Days\", row=3, col=3)\nfig.update_yaxes(title_text=\"ms\", row=3, col=3)\n\n# Update subplot titles font size and color\nfig.update_annotations(font_size=20, font_color=INK)\n\n# Save as PNG and HTML\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}