Scatter Plot with Text Labels Instead of Points — Highcharts

A scatter plot where data points are represented by text labels instead of markers. Each label is positioned at its corresponding coordinates, making the text itself the visual element. This visualization is particularly useful for displaying named entities in 2D space, such as word embeddings, dimensionality reduction outputs, or any scenario where identifying individual items by name is more important than seeing their relative density.

Scatter Plot with Text Labels Instead of Points rendered with Highcharts

Renders

JavaScript source (Highcharts)

// anyplot.ai
// scatter-text: Scatter Plot with Text Labels Instead of Points
// Library: highcharts 12.6.0 | JavaScript 22.23.2
// Quality: 92/100 | Created: 2026-09-02

const t = window.ANYPLOT_TOKENS;

// --- Data (in-memory, deterministic) ----------------------------------------
// Synthetic 2D projection (e.g. a t-SNE/UMAP embedding) of programming
// language names, loosely clustered by language family. Every point is
// rendered as its own name instead of a marker glyph.
const clusters = [
  {
    name: "Data & scientific",
    points: [
      { name: "Python", x: 1.6, y: 4.8 },
      { name: "R", x: 2.6, y: 5.6 },
      { name: "Julia", x: 0.6, y: 5.4 },
      { name: "MATLAB", x: 3.2, y: 6.6 },
      { name: "SAS", x: 3.6, y: 4.4 },
    ],
  },
  {
    name: "Web & frontend",
    points: [
      { name: "JavaScript", x: 5.8, y: 1.4 },
      { name: "TypeScript", x: 6.6, y: 2.4 },
      { name: "PHP", x: 4.8, y: 0.6 },
      { name: "Ruby", x: 5.4, y: -0.6 },
      { name: "Dart", x: 7.2, y: 1.0 },
    ],
  },
  {
    name: "Systems programming",
    points: [
      { name: "C", x: -2.4, y: -0.4 },
      { name: "C++", x: -1.4, y: 0.6 },
      { name: "Rust", x: -3.2, y: 1.2 },
      { name: "Go", x: -2.0, y: 2.0 },
      { name: "Zig", x: -3.6, y: -0.8 },
    ],
  },
  {
    name: "JVM & enterprise",
    points: [
      { name: "Java", x: 3.4, y: -2.6 },
      { name: "Kotlin", x: 4.4, y: -1.8 },
      { name: "Scala", x: 2.6, y: -3.4 },
      { name: "C#", x: 5.2, y: -3.0 },
      { name: "VB.NET", x: 3.8, y: -4.2 },
    ],
  },
  {
    name: "Scripting & ops",
    points: [
      { name: "Bash", x: -4.6, y: 3.8 },
      { name: "Perl", x: -3.8, y: 4.8 },
      { name: "Lua", x: -5.4, y: 4.4 },
      { name: "PowerShell", x: -4.2, y: 5.6 },
      { name: "Groovy", x: -2.8, y: 4.2 },
    ],
  },
];

// --- Chart -------------------------------------------------------------------
// "Data & scientific" is the featured cluster (brand green, drawn first): a
// low-opacity halo behind it gives the chart one focal point instead of five
// visually equal groups. Series order controls z-order, so declaring the
// halo series first keeps it beneath every text label.
const focusHalo = {
  type: "scatter",
  name: "focus-halo",
  showInLegend: false,
  enableMouseTracking: false,
  dataLabels: { enabled: false },
  data: [{ x: 2.32, y: 5.36 }],
  marker: {
    enabled: true,
    radius: 130,
    fillColor: "rgba(0, 158, 115, 0.1)",
    lineWidth: 0,
    states: { hover: { enabled: false } },
  },
};

const clusterSeries = clusters.map((cluster, i) => {
  // Matte red ("Scripting & ops") sits close to the WCAG contrast floor on the
  // near-black dark background; a theme-adaptive ink-colored outline lifts it
  // above the floor there. Every other cluster/theme keeps the page-background
  // outline so it stays invisible, as before.
  const outlineColor = i === 4 && t.theme === "dark" ? t.ink : t.pageBg;
  return {
    type: "scatter",
    name: cluster.name,
    color: t.palette[i],
    data: cluster.points,
    marker: { enabled: false, states: { hover: { enabled: false } } },
    dataLabels: {
      enabled: true,
      format: "{point.name}",
      allowOverlap: false,
      crop: false,
      overflow: "allow",
      align: "center",
      verticalAlign: "middle",
      style: {
        color: t.palette[i],
        fontSize: "15px",
        fontWeight: "600",
        textOutline: `1px ${outlineColor}`,
      },
    },
  };
});

const series = [focusHalo, ...clusterSeries];

Highcharts.chart("container", {
  chart: {
    backgroundColor: "transparent",
    animation: false,
    spacing: [24, 32, 24, 32],
    style: { fontFamily: "inherit" },
  },
  credits: { enabled: false },
  title: {
    text: "scatter-text · javascript · highcharts · anyplot.ai",
    style: { color: t.ink, fontSize: "22px", fontWeight: "600" },
  },
  xAxis: {
    title: {
      text: "t-SNE dimension 1",
      style: { color: t.inkSoft, fontSize: "16px" },
    },
    min: -6.6,
    max: 8.4,
    labels: { enabled: false },
    lineColor: t.inkSoft,
    tickLength: 0,
    gridLineWidth: 1,
    gridLineColor: t.grid,
  },
  yAxis: {
    title: {
      text: "t-SNE dimension 2",
      style: { color: t.inkSoft, fontSize: "16px" },
    },
    min: -5.5,
    max: 7.8,
    labels: { enabled: false },
    lineColor: t.inkSoft,
    tickLength: 0,
    gridLineWidth: 1,
    gridLineColor: t.grid,
  },
  legend: {
    title: {
      text: "Language family",
      style: { color: t.inkSoft, fontSize: "14px" },
    },
    // Marker-free scatter series draw no legend symbol, so the color key
    // lives in the legend text itself instead of a swatch.
    useHTML: true,
    labelFormatter: function () {
      return `<span style="color:${this.color}">${this.name}</span>`;
    },
    itemStyle: { fontSize: "14px", fontWeight: "600" },
    itemHoverStyle: { color: t.ink },
  },
  plotOptions: { series: { animation: false } },
  series,
});

Retrieve this implementation

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

Part of Scatter Plot with Text Labels Instead of Points on anyplot.ai.

Other implementations