import { DotPlot } from "semiotic"
DotPlot (also known as a Cleveland dot plot) visualizes categorical data by placing a single dot along a value axis for each category. It is an effective, minimal alternative to bar charts when the goal is precise comparison of values. Categories are sorted by value by default, making rank easy to read at a glance.
Quick Start
The simplest dot plot requires just data. Categories are sorted by value automatically with a horizontal layout.
import { DotPlot } from "semiotic" const frameProps = { /* --- Data --- */ data: [ { category: "Norway", value: 82.4 }, { category: "Switzerland", value: 81.9 }, { category: "Australia", value: 80.5 }, // ...more data points ], /* --- Process --- */ valueAccessor: "value", categoryAccessor: "category", /* --- Customize --- */ categoryLabel: "Country", valueLabel: "Quality of Life Index" } export default () => { return <DotPlot {...frameProps} /> }
Examples
Colored by Group
Use colorBy to color dots by a categorical field, such as continent or region.
import { DotPlot } from "semiotic" const frameProps = { /* --- Data --- */ data: [ { category: "Norway", value: 82.4, continent: "Europe" }, { category: "Switzerland", value: 81.9, continent: "Europe" }, // ...data with continent field for coloring ], /* --- Process --- */ valueAccessor: "value", categoryAccessor: "category", /* --- Customize --- */ colorBy: "continent", categoryLabel: "Country", valueLabel: "Quality of Life Index" } export default () => { return <DotPlot {...frameProps} /> }
Vertical Orientation
Set orientation to "vertical" andsort to "asc" for a vertical layout with ascending order.
import { DotPlot } from "semiotic" const frameProps = { /* --- Data --- */ data: countryData, /* --- Layout --- */ orientation: "vertical", sort: "asc", /* --- Process --- */ valueAccessor: "value", categoryAccessor: "category", /* --- Customize --- */ dotRadius: 7, valueLabel: "Quality of Life Index" } export default () => { return <DotPlot {...frameProps} /> }
Custom Radius and No Sorting
Increase dotRadius for larger dots and setsort to false to preserve the original data order.
import { DotPlot } from "semiotic" const frameProps = { /* --- Data --- */ data: countryData, /* --- Layout --- */ sort: false, /* --- Process --- */ valueAccessor: "value", categoryAccessor: "category", /* --- Customize --- */ showGrid: true, dotRadius: 8, categoryLabel: "Country", valueLabel: "Quality of Life Index" } export default () => { return <DotPlot {...frameProps} /> }
Props
| Prop | Type | Required | Default | Description |
|---|
data | array | Yes | — | Array of data points with category and value fields. |
categoryAccessor | string | function | — | "category" | Field name or function to access category values. |
valueAccessor | string | function | — | "value" | Field name or function to access numeric values. |
orientation | "vertical" | "horizontal" | — | "horizontal" | Chart orientation. Defaults to horizontal, which is typical for dot plots. |
categoryLabel | string | — | — | Label for the category axis. |
valueLabel | string | — | — | Label for the value axis. |
valueFormat | function | — | — | Format function for value axis tick labels. |
colorBy | string | function | — | — | Field name or function to determine dot color. |
colorScheme | string | array | — | "category10" | Color scheme name or custom colors array. |
sort | boolean | string | function | — | true | Sort categories by value. Accepts true, "asc", "desc", or a custom comparator function. Defaults to true (descending). |
dotRadius | number | — | 5 | Radius of the dots. |
categoryPadding | number | — | 10 | Padding between categories in pixels. |
enableHover | boolean | — | true | Enable hover annotations on dots. |
showGrid | boolean | — | true | Show background grid lines. Defaults to true for dot plots. |
showLegend | boolean | — | true (when colorBy set) | 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: 120, right: 40 } | Margin around the chart area. Left margin is larger to accommodate category labels. |
title | string | — | — | Chart title displayed at the top. |
frameProps | object | — | — | Additional StreamOrdinalFrame props for advanced customization. Escape hatch to the full Frame API. |
Graduating to the Frame
When you need more control — custom marks, range lines, annotations — graduate to StreamOrdinalFramedirectly. Every DotPlot is just a configuredStreamOrdinalFrame under the hood.
Chart (simple)
JSX
import { DotPlot } from "semiotic" <DotPlot data={countryData} categoryAccessor="category" valueAccessor="value" colorBy="continent" dotRadius={6} categoryLabel="Country" valueLabel="Quality of Life" />
Frame (full control)
JSX
import { StreamOrdinalFrame } from "semiotic" <StreamOrdinalFrame data={countryData} oAccessor="category" rAccessor="value" type="point" projection="horizontal" style={d => ({ fill: colorScale(d.continent), r: 6, fillOpacity: 0.8 })} oPadding={10} axes={[ { orient: "left" }, { orient: "bottom", label: "Quality of Life" } ]} pieceHoverAnnotation={true} size={[600, 400]} margin={{ top: 50, bottom: 60, left: 120, right: 40 }} />
The frameProps prop on DotPlot lets you pass any StreamOrdinalFrame prop without fully graduating:
JSX
// Use frameProps as an escape hatch <DotPlot data={countryData} categoryAccessor="category" valueAccessor="value" frameProps={{ annotations: [ { type: "or", category: "Norway", label: "Highest" } ], connectorStyle: { stroke: "#ccc" }, connectorType: { type: "line" } }} />
- BarChart — use bars instead of dots for category comparisons
- SwarmPlot — for distributions with multiple points per category
- StreamOrdinalFrame — the underlying Frame with full control over every rendering detail
- Annotations — adding callouts, highlights, and notes to any visualization
- Tooltips — custom tooltip content and positioning