This document tries to reproduce charts included in the Observable Plot Changelog.

Currently supported Plot version : 0.2.8.

Plot 0.2.3

rect, bar, and rule marks now accept an interval option.

obsplot(aapl) |>
  mark_barX(
    x = "Date",
    interval = JS("d3.utcYear"),
    fill = "Date"
  )

Plot 0.2.1

All marks now support dx and dy constant options.

data(athletes)
obsplot(athletes) |>
  mark_dot(x = "weight", y = "height", dx = -100, dy = 250)
obsplot(athletes) |>
  mark_rect(
    transform_bin(
      list(
        fill = "count",
        title = JS("(bin, {x1, x2, y1, y2}) => `${bin.length} athletes weighing between ${x1} and ${x2} and with a height between ${y1} and ${y2}`")
      ),
      x = "weight", y = "height", inset = 0
    )
  )

Plot 0.2.0

Render functions

Marks can be passed as render functions. This can be achieved in obsplot with mark_function() or mark_svg() :

data(aapl)
obsplot(aapl) |>
  mark_line(x = "Date", y = "Close") |>
  mark_svg("<text x=20% y=20% fill=red>Hello, world!</text>")

When using mark_function, the function definition must be enclosed into an htmlwidgets::JS call. The svg template literal has been imported from Observable standard library and can be used directly :

obsplot(aapl) |>
  mark_line(x = "Date", y = "Close") |>
  mark_function(JS("() => svg`<text x=20% y=20% fill=red>Hello, world!</text>`"))

Marks

All marks now accept a shapeRendering option :

obsplot() |>
  mark_dot(x = 0, y = 0, r = 100, shapeRendering = "crispEdges")

strokeWidth option can be specified as a channel :

df <- data.frame(value = 1:40, stroke = (1:40) / 15)
obsplot(df, height = 60) |>
  mark_dotX(x = "value", strokeWidth = "stroke")

stroke and strokeOpacity for text mark can now be specified as channels :

df <- data.frame(value = LETTERS[1:10], x = 1:10, opacity = seq(0, 1, length.out = 10))
obsplot(df, height = 60) |>
  mark_textX(x = "x", text = "value", stroke = "x", strokeOpacity = "opacity")

Collapsed domains handling in marks that represent continuous intervals :

obsplot(df) |>
  mark_rectY(data = c(1, 1, 1), transform_binX())

Scales

New sort options :

data(alphabet)
obsplot(alphabet) |>
  mark_barY(
    x = "letter", y = "frequency",
    sort = list(x = "y", reverse = TRUE)
  )

New threshold scale type :

obsplot(alphabet) |>
  mark_barY(
    x = "letter", y = "frequency", fill = "frequency",
    sort = list(x = "y", reverse = TRUE)
  ) |>
  scale_y(percent = TRUE) |>
  scale_color(type = "threshold", domain = 0.05)

New diverging color scales options :

data(gistemp)
g <- obsplot(gistemp) |>
  mark_dot(x = "Date", y = "Anomaly", stroke = "Anomaly") |>
  mark_ruleY(0) |>
  opts(grid = TRUE)

g |>
  scale_color(
    type = "diverging", scheme = "BuRd"
  )
g |>
  scale_color(
    type = "diverging", scheme = "BuRd", symmetric = FALSE
  )
g |>
  scale_color(type = "diverging-sqrt")

New axis line option :

obsplot() |>
  opts(grid = TRUE, inset = 6) |>
  scale_x(domain = "ABCDEFGH") |>
  scale_y(domain = c(0, 1), line = TRUE)

Facets

Empty facets are no longer rendered :

library(palmerpenguins)
obsplot(penguins) |>
  mark_dot(x = "bill_depth_mm", y = "bill_length_mm") |>
  mark_frame() |>
  facet(x = "sex", y = "species") |>
  opts(grid = TRUE)

Transforms

New filter, sort and reverse options to bin and group transforms outputs objects :

data(sfcases)
df <- sfcases |> filter(case_disposition == "Death")
obsplot(df) |>
  mark_areaY(
    transform_binX(
      list(y = "sum", filter = NULL),
      x = "specimen_collection_date",
      y = "case_count",
      fill = "transmission_category",
      curve = "step",
      thresholds = JS("d3.utcWeek")
    )
  ) |>
  mark_ruleY(0)

New reducers in bin and group transforms :

obsplot(trends2020, height = 900) |>
  mark_areaY(x = "week", y = "interest", sort = list(fy = "y", reduce = "max-index")) |>
  facet(y = "search", marginLeft = 160) |>
  opts(label = NULL) |>
  scale_x(axis = "top") |>
  scale_y(axis = NULL)

k can be passed directly as first argument to window transforms :

obsplot(gistemp) |>
  mark_ruleY(0) |>
  mark_line(transform_windowY(24, list(x = "Date", y = "Anomaly")))