import { Scatterplot } from "semiotic"
Scatterplot visualizes relationships between two continuous variables by plotting individual data points on an x-y plane. Color and size encoding can reveal additional dimensions in the data. For size-encoded points with a third variable, seeBubbleChart.
Quick Start
The simplest scatterplot requires just data,xAccessor, and yAccessor.
import { Scatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: [ { height: 160, weight: 55 }, { height: 165, weight: 62 }, { height: 170, weight: 68 }, // ...more data points ], /* --- Process --- */ xAccessor: "height", yAccessor: "weight", /* --- Customize --- */ xLabel: "Height (cm)", yLabel: "Weight (kg)" } export default () => { return <Scatterplot {...frameProps} /> }
Examples
Color by Category
Use colorBy to color points by a categorical field. A legend is automatically shown.
import { Scatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: [ { height: 160, weight: 55, group: "A" }, { height: 165, weight: 62, group: "A" }, // ...data with group field for coloring ], /* --- Process --- */ xAccessor: "height", yAccessor: "weight", /* --- Customize --- */ xLabel: "Height (cm)", yLabel: "Weight (kg)", colorBy: "group" } export default () => { return <Scatterplot {...frameProps} /> }
Size Encoding
Use sizeBy to map a third variable to point size, andsizeRange to control the min/max radius.
import { Scatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: [ { height: 160, weight: 55, score: 72 }, { height: 165, weight: 62, score: 85 }, // ...data with score field for sizing ], /* --- Process --- */ xAccessor: "height", yAccessor: "weight", /* --- Customize --- */ xLabel: "Height (cm)", yLabel: "Weight (kg)", sizeBy: "score", sizeRange: [3, 12], pointOpacity: 0.6 } export default () => { return <Scatterplot {...frameProps} /> }
Custom Point Styling
Combine pointRadius, pointOpacity, andshowGrid for a polished look.
import { Scatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: measurementData, /* --- Process --- */ xAccessor: "height", yAccessor: "weight", /* --- Customize --- */ showGrid: true, xLabel: "Height (cm)", yLabel: "Weight (kg)", pointRadius: 7, pointOpacity: 0.5 } export default () => { return <Scatterplot {...frameProps} /> }
Custom Hover Radius
Use hoverRadius to control how far the cursor can be from a point and still trigger a hover. Default is 30px. Increase for sparse charts, decrease for dense ones.
import { Scatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: sampleData, /* --- Process --- */ xAccessor: "height", yAccessor: "weight", /* --- Interact --- */ tooltip: true, /* --- Other --- */ hoverRadius: 60 } export default () => { return <Scatterplot {...frameProps} /> }
Regression Overlay
Set regression to overlay a fitted line. Passtrue for a default linear fit, a method name ("linear" | "polynomial" |"loess") for the method-only shorthand, or a config object for full styling control. The prop is sugar over thetrend annotation — for multiple regression lines or custom anchoring drop into the annotations array directly.
import { Scatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: sampleData, /* --- Process --- */ xAccessor: "height", yAccessor: "weight", /* --- Other --- */ regression: { method: "linear", color: "#ef4444", label: "Trend" } } export default () => { return <Scatterplot {...frameProps} /> }
Use method: "loess" for non-linear data — bandwidth controls how aggressively the curve smooths.
import { Scatterplot } from "semiotic" const frameProps = { /* --- Data --- */ data: sampleData, /* --- Process --- */ xAccessor: "height", yAccessor: "weight", /* --- Other --- */ regression: { method: "loess", bandwidth: 0.5, color: "#8b5cf6", strokeWidth: 2.5 } } export default () => { return <Scatterplot {...frameProps} /> }
Props
| Prop | Type | Required | Default | Description |
|---|
data | array | Yes | — | Array of data points. Each point should have x and y properties. |
xAccessor | string | function | — | "x" | Field name or function to access x values from each data point. |
yAccessor | string | function | — | "y" | Field name or function to access y values from each data point. |
colorBy | string | function | — | — | Field name or function to determine point color. |
colorScheme | string | array | — | "category10" | Color scheme name or custom colors array. |
sizeBy | string | function | — | — | Field name or function to determine point size. |
sizeRange | [number, number] | — | [3, 15] | Min and max radius for points when sizeBy is specified. |
pointRadius | number | — | 5 | Default point radius when sizeBy is not specified. |
pointOpacity | number | — | 0.8 | Opacity of the points. |
regression | boolean | string | object | — | — | Overlay a regression line. true = linear, "linear" | "polynomial" | "loess" = method, or a full RegressionConfig object. Sugar over the trend annotation. |
enableHover | boolean | — | true | Enable hover annotations on data points. |
showGrid | boolean | — | false | Show background grid lines. |
showLegend | boolean | — | true (when colorBy) | Show a legend. Defaults to true when colorBy is specified. |
tooltip | object | function | — | — | Tooltip configuration or render function. |
width | number | — | 600 | Chart width in pixels. |
height | number | — | 400 | Chart height in pixels. |
margin | object | — | { top: 50, bottom: 60, left: 70, right: 40 } | Margin around the chart area. |
xLabel | string | — | — | Label for the x-axis. |
yLabel | string | — | — | Label for the y-axis. |
hoverRadius | number | — | 30 | Maximum distance (px) from a data point to trigger hover. Increase for sparse charts, decrease for dense ones. |
animate | boolean | object | — | false | Enable animated intro and smooth data-change transitions. `true` for defaults (300ms ease-out, intro enabled), or `{ duration, easing, intro }`. Set `{ intro: false }` to disable intro. |
title | string | — | — | Chart title displayed at the top. |
frameProps | object | — | — | Additional StreamXYFrame props for advanced customization. Escape hatch to the full Frame API. |
Graduating to the Frame
When you need more control — custom marks, fully bespoke layouts, per-mark scene primitives — graduate toStreamXYFramedirectly. Every Scatterplot is just a configuredStreamXYFrame under the hood. Common analytical overlays (regression lines, trend bands, anomaly markers) are already first-class on Scatterplot via theregression prop and the annotations array — see the Regression Overlay section.
Chart (simple)
JSX
import { Scatterplot } from "semiotic" <Scatterplot data={measurements} xAccessor="height" yAccessor="weight" colorBy="group" pointRadius={5} xLabel="Height (cm)" yLabel="Weight (kg)" />
Frame (full control)
JSX
import { StreamXYFrame } from "semiotic" <StreamXYFrame points={measurements} xAccessor="height" yAccessor="weight" pointStyle={d => ({ fill: colorScale(d.group), fillOpacity: 0.8, r: 5 })} axes={[ { orient: "left", label: "Weight (kg)" }, { orient: "bottom", label: "Height (cm)" } ]} hoverAnnotation={true} customPointMark={({ d }) => ( <circle r={d.r} strokeWidth={1} stroke="#fff" /> )} size={[600, 400]} />
The frameProps prop on Scatterplot lets you pass any StreamXYFrame prop without fully graduating:
JSX
// Use frameProps as an escape hatch <Scatterplot data={measurements} xAccessor="height" yAccessor="weight" frameProps={{ annotations: [ { type: "enclose", coordinates: outliers, label: "Outliers" } ], customPointMark: ({ d }) => <circle r={d.r} strokeWidth={1} /> }} />
- BubbleChart — scatterplot with a required size dimension for three-variable visualization
- Heatmap — for dense point data, aggregate into color-encoded cells
- LineChart — connect points with lines to show trends
- StreamXYFrame — the underlying Frame with full control over every rendering detail
- Annotations — adding callouts, highlights, and notes to any visualization