Skip to content

Earthquakes Globe

A rotatable globe of earthquake activity. To show land masses, this example loads and parses TopoJSON data in the database. Requires the DuckDB spatial extension.

Loading Example...

Credit: Adapted from an Observable Plot example.

Specification

js
import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
  vg.loadExtension("spatial"),
  vg.loadParquet("earthquakes", "data/earthquakes.parquet"),
  vg.loadSpatial("land", "data/countries-110m.json", {layer: "land"})
]);

const $longitude = vg.Param.value(-180);
const $latitude = vg.Param.value(-30);
const $rotate = vg.Param.array([$longitude, $latitude]);

export default vg.vconcat(
  vg.hconcat(
    vg.slider({label: "Longitude", as: $longitude, min: -180, max: 180, step: 1}),
    vg.slider({label: "Latitude", as: $latitude, min: -90, max: 90, step: 1})
  ),
  vg.plot(
    vg.geo(
      vg.from("land"),
      {geometry: vg.geojson("geom"), fill: "currentColor", fillOpacity: 0.2}
    ),
    vg.sphere(),
    vg.dot(
      vg.from("earthquakes"),
      {
        x: "longitude",
        y: "latitude",
        r: vg.sql`POW(10, magnitude)`,
        stroke: "red",
        fill: "red",
        fillOpacity: 0.2
      }
    ),
    vg.margin(10),
    vg.style("overflow: visible;"),
    vg.projectionType("orthographic"),
    vg.projectionRotate($rotate)
  )
);
yaml
meta:
  title: Earthquakes Globe
  description: >
    A rotatable globe of earthquake activity.
    To show land masses, this example loads and parses TopoJSON data in the database.
    Requires the DuckDB `spatial` extension.
  credit: Adapted from an [Observable Plot example](https://observablehq.com/@observablehq/plot-earthquake-globe).
data:
  earthquakes:
    file: data/earthquakes.parquet
  land:
    type: spatial
    file: data/countries-110m.json
    layer: land
params:
  longitude: -180
  latitude: -30
  rotate: [$longitude, $latitude]
vconcat:
- hconcat:
  - input: slider
    label: Longitude
    as: $longitude
    min: -180
    max: 180
    step: 1
  - input: slider
    label: Latitude
    as: $latitude
    min: -90
    max: 90
    step: 1
- plot:
  - mark: geo
    data: { from: land }
    geometry: { geojson: geom }
    fill: currentColor
    fillOpacity: 0.2
  - mark: sphere
  - mark: dot
    data: { from: earthquakes }
    x: longitude
    y: latitude
    r: { sql: "POW(10, magnitude)" }
    stroke: red
    fill: red
    fillOpacity: 0.2
  margin: 10
  style: "overflow: visible;"
  projectionType: orthographic
  projectionRotate: $rotate
json
{
  "meta": {
    "title": "Earthquakes Globe",
    "description": "A rotatable globe of earthquake activity. To show land masses, this example loads and parses TopoJSON data in the database. Requires the DuckDB `spatial` extension.\n",
    "credit": "Adapted from an [Observable Plot example](https://observablehq.com/@observablehq/plot-earthquake-globe)."
  },
  "data": {
    "earthquakes": {
      "file": "data/earthquakes.parquet"
    },
    "land": {
      "type": "spatial",
      "file": "data/countries-110m.json",
      "layer": "land"
    }
  },
  "params": {
    "longitude": -180,
    "latitude": -30,
    "rotate": [
      "$longitude",
      "$latitude"
    ]
  },
  "vconcat": [
    {
      "hconcat": [
        {
          "input": "slider",
          "label": "Longitude",
          "as": "$longitude",
          "min": -180,
          "max": 180,
          "step": 1
        },
        {
          "input": "slider",
          "label": "Latitude",
          "as": "$latitude",
          "min": -90,
          "max": 90,
          "step": 1
        }
      ]
    },
    {
      "plot": [
        {
          "mark": "geo",
          "data": {
            "from": "land"
          },
          "geometry": {
            "geojson": "geom"
          },
          "fill": "currentColor",
          "fillOpacity": 0.2
        },
        {
          "mark": "sphere"
        },
        {
          "mark": "dot",
          "data": {
            "from": "earthquakes"
          },
          "x": "longitude",
          "y": "latitude",
          "r": {
            "sql": "POW(10, magnitude)"
          },
          "stroke": "red",
          "fill": "red",
          "fillOpacity": 0.2
        }
      ],
      "margin": 10,
      "style": "overflow: visible;",
      "projectionType": "orthographic",
      "projectionRotate": "$rotate"
    }
  ]
}