Recurrence Plot for Nonlinear Time Series — MUI X Charts

A recurrence plot is a binary or distance-based matrix visualization that reveals when states in a dynamical system recur over time. Both axes represent time indices, and a point is plotted at position (i, j) when the system state at time i is sufficiently similar to the state at time j (distance below a threshold). The resulting symmetric matrix exposes hidden structure in complex, nonlinear dynamics — diagonal lines indicate determinism, vertical/horizontal lines reveal laminar states, and block structures signal regime changes.

Recurrence Plot for Nonlinear Time Series rendered with MUI X Charts

Renders

JavaScript source (MUI X Charts)

// anyplot.ai
// recurrence-basic: Recurrence Plot for Nonlinear Time Series
// Library: muix 7.29.1 | JavaScript 22.22.3
// Quality: 87/100 | Created: 2026-06-10
//# anyplot-orientation: square
// anyplot.ai
// recurrence-basic: Recurrence Plot for Nonlinear Time Series
// Library: MUI X Charts | React | Node 22
// License: @mui/x-charts — MIT (community). Pro/Premium are out of scope.
// Quality: pending | Created: 2026-06-10

import { ChartContainer } from "@mui/x-charts/ChartContainer";
import { ScatterPlot } from "@mui/x-charts/ScatterChart";
import { ChartsXAxis } from "@mui/x-charts/ChartsXAxis";
import { ChartsYAxis } from "@mui/x-charts/ChartsYAxis";
import { ChartsGrid } from "@mui/x-charts/ChartsGrid";
import { useDrawingArea } from "@mui/x-charts/hooks";

const t = window.ANYPLOT_TOKENS;

// Logistic map — chaotic regime (r = 3.95), deterministic seed via fixed start
const N = 300;
const r = 3.95;
const ts: number[] = [0.4];
for (let i = 1; i < N; i++) {
  ts.push(r * ts[i - 1] * (1 - ts[i - 1]));
}

// Time-delay embedding: state[i] = [ts[i], ts[i + tau]] (Takens' theorem)
const tau = 5;
const M = N - tau;
const states = Array.from({ length: M }, (_, i) => [ts[i], ts[i + tau]]);

// Binary recurrence: pairs (i, j) where Euclidean distance < epsilon
const epsilon = 0.15;
const recPts: { x: number; y: number; id: number }[] = [];
let ptId = 0;
for (let i = 0; i < M; i++) {
  for (let j = 0; j < M; j++) {
    const dx = states[i][0] - states[j][0];
    const dy = states[i][1] - states[j][1];
    if (dx * dx + dy * dy < epsilon * epsilon) {
      recPts.push({ x: i, y: j, id: ptId++ });
    }
  }
}

const TITLE_H = 56;

// Annotated identity line (i = j) — drawn via useDrawingArea hook in SVG space.
// In MUI X linear scatter axes, data (0,0) maps to SVG (left, top+height) and
// data (M-1, M-1) maps to SVG (left+width, top), so this diagonal is exact.
function IdentityLine() {
  const { left, top, width, height } = useDrawingArea();
  const labelX = left + width * 0.87;
  const labelY = top + height * 0.07;
  return (
    <g>
      <line
        x1={left}
        y1={top + height}
        x2={left + width}
        y2={top}
        stroke={t.amber}
        strokeWidth={2}
        strokeDasharray="9 5"
        opacity={0.8}
      />
      <text
        x={labelX}
        y={labelY}
        fill={t.amber}
        textAnchor="middle"
        opacity={0.9}
        style={{ fontSize: 12, fontFamily: "Inter, system-ui, sans-serif", fontWeight: 500 }}
      >
        i = j
      </text>
    </g>
  );
}

export default function Chart() {
  const W = window.ANYPLOT_SIZE.width;
  const H = window.ANYPLOT_SIZE.height;
  const side = H - TITLE_H;

  return (
    <div
      style={{
        width: W,
        height: H,
        background: t.pageBg,
        fontFamily: "Inter, system-ui, sans-serif",
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
      }}
    >
      <div
        style={{
          height: TITLE_H,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        <span style={{ fontSize: 22, fontWeight: 600, color: t.ink }}>
          recurrence-basic · javascript · muix · anyplot.ai
        </span>
      </div>
      <ChartContainer
        width={side}
        height={side}
        skipAnimation
        colors={[t.palette[0]]}
        margin={{ top: 15, bottom: 72, left: 80, right: 25 }}
        series={[
          {
            type: "scatter",
            data: recPts,
            markerSize: 2,
            label: "Recurrent",
          },
        ]}
        xAxis={[
          {
            min: 0,
            max: M - 1,
            label: "Time Index i",
            tickLabelStyle: { fontSize: 11 },
            labelStyle: { fontSize: 13 },
          },
        ]}
        yAxis={[
          {
            min: 0,
            max: M - 1,
            label: "Time Index j",
            tickLabelStyle: { fontSize: 11 },
            labelStyle: { fontSize: 13 },
          },
        ]}
        sx={{
          "& .MuiChartsLegend-root": { display: "none" },
          "& .MuiChartsAxis-line": { display: "none" },
          "& .MuiChartsGrid-line": { stroke: t.grid, strokeWidth: 1 },
        }}
      >
        <ChartsGrid vertical horizontal />
        <ScatterPlot />
        <ChartsXAxis />
        <ChartsYAxis />
        <IdentityLine />
      </ChartContainer>
    </div>
  );
}

Retrieve this implementation

Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/recurrence-basic/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": "recurrence-basic",
  "language": "javascript",
  "library": "muix",
  "page": "https://anyplot.ai/recurrence-basic/javascript/muix",
  "hub": "https://anyplot.ai/recurrence-basic",
  "code_json": "https://api.anyplot.ai/specs/recurrence-basic/muix/code",
  "spec_json": "https://api.anyplot.ai/specs/recurrence-basic",
  "render_light_png": "https://storage.googleapis.com/anyplot-images/plots/recurrence-basic/javascript/muix/plot-light.png",
  "render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/recurrence-basic/javascript/muix/plot-dark.png",
  "interactive_light_html": "https://storage.googleapis.com/anyplot-images/plots/recurrence-basic/javascript/muix/plot-light.html",
  "interactive_dark_html": "https://storage.googleapis.com/anyplot-images/plots/recurrence-basic/javascript/muix/plot-dark.html",
  "quality_score": 87.0,
  "license": "MIT",
  "guide": "https://anyplot.ai/llms.txt"
}

Part of Recurrence Plot for Nonlinear Time Series on anyplot.ai.

Other implementations