Subplot Grid Layout — MUI X Charts

A customizable grid of multiple subplots allowing different plot types in each cell, with shared or independent axes. Unlike faceted plots that repeat the same visualization for data subsets, subplot grids enable combining distinct visualizations (scatter, line, bar, histogram, etc.) into a cohesive multi-panel figure for comprehensive data presentation.

Subplot Grid Layout rendered with MUI X Charts

Renders

JavaScript source (MUI X Charts)

// anyplot.ai
// subplot-grid: Subplot Grid Layout
// Library: muix 7.29.1 | JavaScript 22.23.2
// Quality: 85/100 | Created: 2026-09-09
//# anyplot-orientation: landscape
// anyplot.ai
// subplot-grid: Subplot Grid Layout
// Library: MUI X Charts | React | Node 22
// License: @mui/x-charts — MIT (community). Pro/Premium are out of scope.
// Quality: pending | Created: 2026-09-09
import { LineChart } from "@mui/x-charts/LineChart";
import { BarChart } from "@mui/x-charts/BarChart";
import { ScatterChart } from "@mui/x-charts/ScatterChart";
import { PieChart } from "@mui/x-charts/PieChart";
import { ChartsReferenceLine } from "@mui/x-charts/ChartsReferenceLine";
import { Box, Typography } from "@mui/material";

const t = window.ANYPLOT_TOKENS;
const W = window.ANYPLOT_SIZE.width;
const H = window.ANYPLOT_SIZE.height;

// --- Layout (2x2 grid: figure title + 4 independent panels) ----------------
const FIGURE_TITLE_H = 48;
const OUTER_GAP = 16;
const CELL_GAP = 20;
const CELL_TITLE_H = 26;
const GRID_W = W - OUTER_GAP * 2;
const GRID_H = H - FIGURE_TITLE_H - OUTER_GAP * 2;
const CELL_W = (GRID_W - CELL_GAP) / 2;
const CELL_H = (GRID_H - CELL_GAP) / 2;
const CHART_H = CELL_H - CELL_TITLE_H;

// --- Data (in-memory, deterministic LCG) ------------------------------------
function makeRng(seed: number) {
  let state = seed >>> 0;
  return () => {
    state = (state * 1664525 + 1013904223) >>> 0;
    return state / 4294967296;
  };
}
const rng = makeRng(42);

const dayLabels = Array.from({ length: 18 }, (_, i) => `D${i + 1}`);

let price = 128;
const closingPrices = dayLabels.map(() => {
  price += (rng() - 0.47) * 2.4;
  return Math.round(price * 100) / 100;
});

const peakPrice = Math.max(...closingPrices);

const tradingVolume = dayLabels.map(() => Math.round(420_000 + rng() * 380_000));

const priceVolumePoints = closingPrices.map((p, i) => ({
  id: i,
  x: tradingVolume[i],
  y: p,
}));

const sectorAllocation = [
  { id: 0, value: 34, label: "Technology" },
  { id: 1, value: 24, label: "Healthcare" },
  { id: 2, value: 22, label: "Financials" },
  { id: 3, value: 20, label: "Energy" },
];

// --- Chart (default-exported component — the harness mounts it) -----------
export default function Chart() {
  return (
    <Box
      sx={{
        width: W,
        height: H,
        bgcolor: "transparent",
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
      }}
    >
      <Typography
        sx={{
          height: FIGURE_TITLE_H,
          lineHeight: `${FIGURE_TITLE_H}px`,
          fontSize: 22,
          fontWeight: 600,
          color: t.ink,
        }}
      >
        subplot-grid · javascript · muix · anyplot.ai
      </Typography>

      <Box
        sx={{
          display: "grid",
          gridTemplateColumns: `repeat(2, ${CELL_W}px)`,
          gridTemplateRows: `repeat(2, ${CELL_H}px)`,
          gap: `${CELL_GAP}px`,
        }}
      >
        {/* Top-left: line chart — price trend, shares the day-index axis with volume */}
        <Box>
          <Typography sx={{ height: CELL_TITLE_H, fontSize: 15, fontWeight: 500, color: t.ink }}>
            Closing Price (18 trading days)
          </Typography>
          <LineChart
            width={CELL_W}
            height={CHART_H}
            colors={[t.palette[0]]}
            skipAnimation
            grid={{ horizontal: true }}
            slotProps={{ legend: { hidden: true } }}
            margin={{ left: 56, right: 16, top: 8, bottom: 40 }}
            xAxis={[{ scaleType: "point", data: dayLabels, label: "Trading Day" }]}
            yAxis={[{ label: "Price ($)" }]}
            series={[{ data: closingPrices, label: "Close", showMark: false, curve: "monotoneX" }]}
          >
            <ChartsReferenceLine
              y={peakPrice}
              label={`Peak $${peakPrice.toFixed(2)}`}
              labelAlign="end"
              lineStyle={{ stroke: t.amber, strokeDasharray: "4 4" }}
              labelStyle={{ fill: t.amber, fontSize: 12, fontWeight: 600 }}
            />
          </LineChart>
        </Box>

        {/* Top-right: bar chart — volume, shares the day-index axis with price */}
        <Box>
          <Typography sx={{ height: CELL_TITLE_H, fontSize: 15, fontWeight: 500, color: t.ink }}>
            Trading Volume, shares (18 trading days)
          </Typography>
          <BarChart
            width={CELL_W}
            height={CHART_H}
            colors={[t.palette[0]]}
            skipAnimation
            grid={{ horizontal: true }}
            slotProps={{ legend: { hidden: true } }}
            margin={{ left: 56, right: 16, top: 8, bottom: 40 }}
            xAxis={[{ scaleType: "band", data: dayLabels, label: "Trading Day" }]}
            yAxis={[{ label: "Volume (K)", valueFormatter: (v: number) => `${Math.round(v / 1000)}` }]}
            series={[{ data: tradingVolume, label: "Volume" }]}
          />
        </Box>

        {/* Bottom-left: scatter chart — price vs. volume, fully independent axes */}
        <Box>
          <Typography sx={{ height: CELL_TITLE_H, fontSize: 15, fontWeight: 500, color: t.ink }}>
            Price vs. Volume Correlation
          </Typography>
          <ScatterChart
            width={CELL_W}
            height={CHART_H}
            colors={[t.palette[0]]}
            skipAnimation
            grid={{ horizontal: true, vertical: true }}
            slotProps={{ legend: { hidden: true } }}
            margin={{ left: 64, right: 20, top: 8, bottom: 40 }}
            xAxis={[{ label: "Volume (shares)", valueFormatter: (v: number) => `${Math.round(v / 1000)}K` }]}
            yAxis={[{ label: "Price ($)" }]}
            series={[{ data: priceVolumePoints, markerSize: 9 }]}
          />
        </Box>

        {/* Bottom-right: pie chart — sector allocation, independent, no cartesian axes */}
        <Box>
          <Typography sx={{ height: CELL_TITLE_H, fontSize: 15, fontWeight: 500, color: t.ink }}>
            Portfolio Sector Allocation
          </Typography>
          <Box sx={{ display: "flex", alignItems: "center", height: CHART_H, gap: "24px" }}>
            <PieChart
              width={CHART_H}
              height={CHART_H}
              colors={t.palette}
              skipAnimation
              slotProps={{ legend: { hidden: true } }}
              sx={{ "& .MuiPieArcLabel-root": { fill: "#FFFFFF", fontSize: 14, fontWeight: 600 } }}
              series={[
                {
                  data: sectorAllocation,
                  innerRadius: CHART_H * 0.17,
                  outerRadius: CHART_H * 0.47,
                  paddingAngle: 2,
                  cx: CHART_H / 2,
                  cy: CHART_H / 2,
                  arcLabel: (item) => `${item.value}%`,
                  arcLabelMinAngle: 15,
                },
              ]}
            />
            <Box sx={{ display: "flex", flexDirection: "column", gap: "10px" }}>
              {sectorAllocation.map((sector, i) => (
                <Box key={sector.id} sx={{ display: "flex", alignItems: "center", gap: "8px" }}>
                  <Box sx={{ width: 14, height: 14, borderRadius: "3px", bgcolor: t.palette[i] }} />
                  <Typography sx={{ fontSize: 15, color: t.ink }}>{sector.label}</Typography>
                </Box>
              ))}
            </Box>
          </Box>
        </Box>
      </Box>
    </Box>
  );
}

Retrieve this implementation

Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/subplot-grid/muix/code. Any spec id and library id listed in llms-full.txt fit the same URL shape; every URL below is complete and callable.

{
  "spec_id": "subplot-grid",
  "language": "javascript",
  "library": "muix",
  "page": "https://anyplot.ai/subplot-grid/javascript/muix",
  "hub": "https://anyplot.ai/subplot-grid",
  "code_json": "https://api.anyplot.ai/specs/subplot-grid/muix/code",
  "spec_json": "https://api.anyplot.ai/specs/subplot-grid",
  "render_light_png": "https://storage.googleapis.com/anyplot-images/plots/subplot-grid/javascript/muix/plot-light.png",
  "render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/subplot-grid/javascript/muix/plot-dark.png",
  "interactive_light_html": "https://storage.googleapis.com/anyplot-images/plots/subplot-grid/javascript/muix/plot-light.html",
  "interactive_dark_html": "https://storage.googleapis.com/anyplot-images/plots/subplot-grid/javascript/muix/plot-dark.html",
  "quality_score": 85.0,
  "license": "MIT",
  "guide": "https://anyplot.ai/llms.txt"
}

Part of Subplot Grid Layout on anyplot.ai.

Other implementations