Partial Derivative Explorer

Visualise both partial derivatives of a two-variable function f(x, y) as side-by-side slices. The left panel renders f(·, y₀) along x with the tangent at x₀ (slope = ∂f/∂x); the right panel renders f(x₀, ·) along y with the tangent at y₀ (slope = ∂f/∂y). Partials are estimated by symmetric finite differences, so any caller-supplied fn works without needing an analytical derivative.

Partial derivatives of f(x, y)x = 1.00 · y = 1.00 · f = 0.000
∂f/∂xy = 1.00
-2-1012-5-4-3-2-10
∂f/∂yx = 1.00
-2-1012-5-4-3-2-10
∂f/∂x ≈ 0.000∂f/∂y ≈ 0.000dh = 0.01
1.00
1.00
Customize
Function
x·y − x²/2 − y²/2
Evaluation point
1.00
1.00
Tangents

Installation

npx shadcn@latest add https://craftbits.dev/r/partial-derivative-explorer.json

Usage

import { PartialDerivativeExplorer } from "@craft-bits/core";
 
<PartialDerivativeExplorer defaultX={1} defaultY={1} />

Probe a saddle and watch the two slices respond independently:

<PartialDerivativeExplorer
  fn={(x, y) => x * x - y * y}
  xRange={[-2, 2]}
  yRange={[-2, 2]}
  defaultX={0.5}
  defaultY={0.5}
/>

Drive x and y from outside:

const [x, setX] = useState(1);
const [y, setY] = useState(1);
 
<PartialDerivativeExplorer
  fn={(x, y) => Math.sin(x) * Math.cos(y)}
  x={x}
  y={y}
  onXChange={setX}
  onYChange={setY}
/>

Understanding the component

  1. Two slices, two panels. For the current evaluation point (x₀, y₀) the left panel renders f(·, y₀) over xRange and the right panel renders f(x₀, ·) over yRange. Each panel auto-fits its value axis to its sampled slice and pads by 15% so the curve never grazes the frame.
  2. Tangent lines visualise the partials. The left panel's tangent at x₀ has slope ∂f/∂x; the right panel's tangent at y₀ has slope ∂f/∂y. Both span the full visible axis so the slope is easy to read off.
  3. Symmetric finite differences. Each partial is estimated as (f(x+dh, y) - f(x-dh, y)) / (2·dh) with a configurable dh (default 0.01). Second-order accurate; works for any fn.
  4. Spring transitions. Curves, tangents, and markers animate with SPRINGS.smooth. prefers-reduced-motion: reduce collapses every spring to an instant swap.
  5. Auto-clamped sliders. xRange and yRange drive LabeledSlider min / max / step. Stale controlled values outside the range are clamped on render so the curve always stays sensible.
  6. Controlled and uncontrolled, twice. Both x and y accept value + onChange for controlled use, or default* for uncontrolled.

Props

PropTypeDefaultDescription
fn(x: number, y: number) => number(x,y) => x*y - x²/2 - y²/2Two-variable function under exploration.
xRangereadonly [number, number][-2, 2]Visible x-axis domain.
yRangereadonly [number, number][-2, 2]Visible y-axis domain.
xnumberControlled x evaluation point.
defaultXnumbermidpoint of xRangeUncontrolled initial x.
onXChange(x: number) => voidFires on every x slider drag.
ynumberControlled y evaluation point.
defaultYnumbermidpoint of yRangeUncontrolled initial y.
onYChange(y: number) => voidFires on every y slider drag.
showTangentsbooleantrueRender tangent lines on both panels.
dhnumber0.01Finite-difference step for partial estimation.
transitionTransitionSPRINGS.smoothSpring for tangent / marker follow.
classNamestringMerged onto the root via cn().

Accessibility

  • The whole figure is role="figure" with aria-labelledby and aria-describedby pointing at the heading and live summary.
  • Each panel is role="img" with an aria-label naming the slice and pinned-variable value.
  • An aria-live="polite" summary above the panels reads out x, y, and f(x, y) whenever anything changes.
  • Sliders are native <input type="range"> — full keyboard ( / , Home / End, Page Up / Page Down) and AT support out of the box.
  • Animation respects prefers-reduced-motion: reduce.

Credits

  • Extracted from: craftingattention (app/src/lessons/primitives/math/PartialDerivativeExplorer.tsx). Stripped the lesson-specific stage state machine, narration heuristics, pinned-variable preset buttons, drag-on-curve handle, and f(x, y) = x²y hard-coding; generalised to any caller-provided fn, swapped the analytical derivative for symmetric finite differences, replaced bespoke pin buttons with LabeledSliders, and added controlled / uncontrolled state pairs for both x and y.