# Getting started

Observable Plot supports a variety of environments.

## Try Plot online

The fastest way to get started (and get help) with Observable Plot is on [Observable](/content/site-root.html)! Plot is available by default in notebooks as part of Observable’s standard library. To use Plot, simply return the generated plot from a cell like so:

```js
Plot.rectY({length: 10000}, Plot.binX({y: "count"}, {x: d3.randomNormal()})).plot()
```

Observable includes a variety of Plot snippets when you click **+** to add a cell, as well as convenient [sample datasets](/content/@observablehq/sample-datasets/index.html) to try out Plot features. Or upload a CSV or JSON file to start playing with your data. You can even use [Observable’s chart cell](/content/@observablehq/chart-cell/index.html), which uses Plot’s [auto mark](/content/plot/marks/auto/index.html) under the hood, to create quick charts without writing code! You can then eject to JavaScript by clicking **+** to see the equivalent Plot code.

## Plot in vanilla HTML

In vanilla HTML, you can load Plot from a CDN such as jsDelivr or you can download it locally. We recommend using the CDN-hosted ES module bundle as it automatically loads Plot’s dependency on [D3](https://d3js.org/). But for those who need it, we also provide a UMD bundle that exports the `Plot` global when loaded as a plain script.

```html
<!DOCTYPE html>
<div id="myplot"></div>
<script type="module">

import * as Plot from "https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6/+esm";

const plot = Plot.rectY({length: 10000}, Plot.binX({y: "count"}, {x: Math.random})).plot();
const div = document.querySelector("#myplot");
div.append(plot);

</script>
```

Plot returns a detached DOM element — either an [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG) or [HTML figure](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure) element. In vanilla web development, this means you need to insert the generated plot into the page to see it. Typically this is done by selecting a DOM element (such as a DIV with a unique identifier, like `myplot` above), and then calling [_element_.append](https://developer.mozilla.org/en-US/docs/Web/API/Element/append).

## Installing from npm

If you’re developing a web application using Node, you can install Plot via pnpm, npm, yarn, or your preferred package manager.

```bash
pnpm add @observablehq/plot
```

```bash
npm install @observablehq/plot
```

```bash
yarn add @observablehq/plot
```

You can then load Plot into your app as:

```js
import * as Plot from "@observablehq/plot";
```

## Plot in React

We recommend two approaches for Plot in React depending on your needs.

The first is to server-side render (SSR) plots. This minimizes distracting reflow on page load, improving the user experience. For this approach, use the [**document** plot option](/content/plot/features/plots/index.html) to tell Plot to render with React’s virtual DOM. For example, here is a PlotFigure component:

```js
import * as Plot from "@observablehq/plot";
import {createElement as h} from "react";

export default function PlotFigure({options}) {
  return Plot.plot({...options, document: new Document()}).toHyperScript();
}
```

Then, to use:

```jsx
import * as Plot from "@observablehq/plot";
import PlotFigure from "./PlotFigure.js";
import penguins from "./penguins.json";

export default function App() {
  return (
    <div>
      <h1>Penguins</h1>
      <PlotFigure
        options={{
          marks: [
            Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"})
          ]
        }}
      />
    </div>
  );
}
}
```

Server-side rendering is only practical for simple plots of small data; complex plots, such as geographic maps or charts with thousands of elements, are better rendered on the client because the serialized SVG is large. For this second approach, use [useRef](https://react.dev/reference/react/useRef) to get a reference to a DOM element, and then [useEffect](https://react.dev/reference/react/useEffect) to generate and insert your plot.

## Plot in Vue

As with React, you can use either server- or client-side rendering with Plot and Vue.

For server-side rendering (SSR), use the [**document** plot option](/content/plot/features/plots/index.html) to render to Vue’s virtual DOM. For example, here is a PlotFigure component:

```js
import * as Plot from "@observablehq/plot";
import {h} from "vue";

export default {
  props: {
    options: Object
  },
  render() {
    return Plot.plot({
      ...this.options,
      document: new Document()
    }).toHyperScript();
  }
};
```

Then, to use:

```vue
<script setup>
import * as Plot from "@observablehq/plot";
import PlotFigure from "./components/PlotFigure.js";
import penguins from "./assets/penguins.json";
</script>

<template>
  <h1>Plot + Vue</h1>
  <PlotFigure
    :options="{
      marks: [
        Plot.dot(penguins, {x: 'culmen_length_mm', y: 'culmen_depth_mm'}),
      ],
    }"
  />
</template>
```

For client-side rendering, use a [render function](https://vuejs.org/guide/extras/render-function.html) with a [mounted](https://vuejs.org/api/options-lifecycle.html#mounted) lifecycle directive. After the component mounts, render the plot and then insert it into the page.

## Plot in Svelte

Here’s an example of client-side rendering in Svelte:

```svelte
<script lang="ts">
  import * as Plot from '@observablehq/plot';
  import * as d3 from 'd3';

let div: HTMLElement | undefined = $state();
  let data = $state(d3.ticks(-2, 2, 200).map(Math.sin));

function onMousemove(event: MouseEvent) {
    const [x, y] = d3.pointer(event);
    data = data.slice(-200).concat(Math.atan2(x, y));
  }

$effect(() => {
    div?.firstChild?.remove(); // remove old chart, if any
    div?.append(Plot.lineY(data).plot({ grid: true })); // add the new chart
  });
</script>

<div onmousemove={onMousemove} bind:this={div} role="img"></div>
```

## Plot in Node.js

You can use Plot to server-side render SVG or PNG in Node.js. Use [JSDOM](https://github.com/jsdom/jsdom) for a DOM implementation via the **document** option, then serialize the generated plot using **outerHTML**.

```js
import {readFile} from "node:fs/promises";
import * as Plot from "@observablehq/plot";
import * as d3 from "d3";
import {JSDOM} from "jsdom";

const penguins = d3.csvParse(await readFile("./penguins.csv", "utf-8"), d3.autoType);

const plot = Plot.plot({
  document: new JSDOM("{}").window.document,
  marks: [
    Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", stroke: "species"})
  ]
});

process.stdout.write(plot.outerHTML);
```
