plot icon indicating copy to clipboard operation
plot copied to clipboard

New syntax for declaring facets from a mark

Open mbostock opened this issue 3 years ago • 1 comments

Broken out of #1041 and https://github.com/observablehq/plot/commit/0c2fadffd17cb77a81de33b1998ec20d2afe8858.

Instead of this:

Plot.plot({
  facets: {
    data: penuins,
    x: "sex",
    y: "island"
  },
  marks: [
    Plot.dot(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm"
    })
  ]
})

You could say:

Plot.plot({
  marks: [
    Plot.dot(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm",
      fx: "sex",
      fy: "island"
    })
  ]
})

Or in shorthand, instead of this:

Plot.dot(penguins, {
  x: "culmen_length_mm",
  y: "culmen_depth_mm"
}).plot({
  facets: {
    data: penuins,
    x: "sex",
    y: "island"
  }
})

You could say:

Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", fx: "sex", fy: "island"}).plot()

mbostock avatar Oct 10 '22 17:10 mbostock

If multiple marks specify _fx_and fy, what happens? It means that marks can use different data, but share the same fx and fy scales. In other words, the domains for the fx and fy scales will need to be unioned across all marks that define fx and fy channels (just like the other scales). So this:

Plot.plot({
  facet: {
    data: penguins,
    x: "sex",
    y: "island"
  },
  marks: [
    Plot.dot(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm"
    }),
    Plot.text(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm"
    })
  ]
})

Is equivalent to this:

Plot.plot({
  marks: [
    Plot.dot(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm",
      fx: "sex",
      fy: "island"
    }),
    Plot.text(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm",
      fx: "sex",
      fy: "island"
    })
  ]
})

And likewise, this:

Plot.plot({
  facet: {
    data: penguins,
    x: "sex",
    y: "island"
  },
  marks: [
    Plot.dot(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm"
    }),
    Plot.text(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm",
      facet: false
    })
  ]
})

Is equivalent to this:

Plot.plot({
  marks: [
    Plot.dot(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm",
      fx: "sex",
      fy: "island"
    }),
    Plot.text(penguins, {
      x: "culmen_length_mm",
      y: "culmen_depth_mm"
    })
  ]
})

And then the cool thing, if I want to have e.g. one label per facet, I no longer have to use the selectFirst transform; I can instead provide data whose fx and fy channels map to the expected values.

mbostock avatar Oct 10 '22 17:10 mbostock