Skip to content


Interaction allows reading values out of a plot (details on demand), or fluidly changing a view of data without editing code (zoom and filter). There are a variety of ways to achieve interaction with Plot, including built-in interaction features and development techniques with frameworks such as Observable and React.


When looking at a scatterplot, the reader may wonder, what abstract values does this dot represent?

The pointer transform can provide an answer: it dynamically filters a mark such that only the data closest to the pointer (such as the mouse) is rendered. The pointer transform is often paired with the tip mark for interactive tooltips, revealing exact values as the pointer moves over the plot. The tip can show additional fields not otherwise visible, such as the name and sport of Olympic athletes below.

js, {
  x: "weight",
  y: "height",
  stroke: "sex",
  channels: {name: "name", sport: "sport"},
  tip: true

The crosshair mark uses the pointer transform internally to display a rule and a text showing the x (horizontal↔︎ position) and y (vertical↕︎ position) value of the nearest data.

  marks: [, {x: "weight", y: "height", stroke: "sex"}),
    Plot.crosshair(olympians, {x: "weight", y: "height"})

These values are displayed atop the axes on the edge of the frame; unlike the tip mark, the crosshair mark will not obscure other marks in the plot.


Support for selecting points within a plot through direct manipulation is under development. If you are interested in this feature, please upvote #5. See #721 for some early work on brushing.


Support for interactive panning and zooming is planned for a future release. If you are interested in this feature, please upvote #1590.


Support for declarative animation is planned for a future release. If you are interested in this feature, please upvote #166. See #995 for some early work on a time channel.

Custom reactivity

With the exception of render transforms (see the pointer transform implementation), Plot does not currently provide incremental re-rendering (partial updates to previously-rendered plots) or animated transitions between views.

That said, you can simply throw away an old plot and replace it with a new one! This allows plotting of dynamic data: data which can change in real-time as it streams in, or because it is derived in response to external inputs such as range sliders and search boxes.

On Observable, you can use viewof in conjunction with Observable Inputs (or other plots!) for interactivity. If your cell references another cell, it will automatically re-run whenever the upstream cell’s value changes. For example, try dragging the slider in this hexbin example. In React, use useEffect and useRef to re-render the plot when data changes. In Vue, use ref. For more, see our getting started guide.

You can also manipulate the SVG that Plot creates, if you are comfortable using lower-level APIs; see examples by Mike Freeman and Philippe Rivière.