Skip to content

“Zero-dimensional” group and more flexible normalization… #261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mbostock opened this issue Mar 20, 2021 · 3 comments · Fixed by #264
Closed

“Zero-dimensional” group and more flexible normalization… #261

mbostock opened this issue Mar 20, 2021 · 3 comments · Fixed by #264
Labels
enhancement New feature or request

Comments

@mbostock
Copy link
Member

mbostock commented Mar 20, 2021

I’m trying to make a stacked bar chart of Penguins by sex using the group transform. I can do this using Plot.groupX, but it requires a dummy x definition:

untitled-43

Plot.plot({
  y: {
    grid: true
  },
  marks: [
    Plot.barY(penguins, Plot.stackY(Plot.groupX({x: () => 1, fill: "sex", normalize: true}))),
    Plot.ruleY([0])
  ]
})

I can overwrite the x definition to get what I want, so it’s possible but awkward:

untitled-42

Plot.plot({
  y: {
    grid: true
  },
  marks: [
    Plot.barY(penguins, Plot.stackY({...Plot.groupX({x: () => 1, fill: "sex", normalize: true}), x: null})),
    Plot.ruleY([0])
  ]
})

What I want is some way for groupX’s x to be optional (maybe I want it to default to undefined, rather than defaulting to identity, but I suppose having it default to identity would be okay if I can say x: null):

Plot.plot({
  y: {
    grid: true
  },
  marks: [
    Plot.barY(penguins, Plot.stackY(Plot.groupX({fill: "sex", normalize: true}))),
    Plot.ruleY([0])
  ]
})

I’m not sure “groupX” is still the right name for this transform, but maybe it‘s fine, since it will output frequency to the y channel which is what I want.

The next thing I want is for this to work with faceting:

untitled-44

Plot.plot({
  y: {
    grid: true
  },
  facet: {
    data: penguins,
    x: "species"
  },
  marks: [
    Plot.barY(penguins, Plot.stackY({
      ...Plot.groupX({
        x: () => 1, // TODO
        fill: "sex",
        order: "z",
        normalize: true
      }),
      x: null
    })),
    Plot.ruleY([0])
  ]
})

And here the problem is that neither normalize: true nor normalize: "z" do what I want, because I want to normalize to the facet. Maybe normalize: "facet" should be an option? That’s certainly easy to implement.

@mbostock mbostock added the enhancement New feature or request label Mar 20, 2021
@mbostock
Copy link
Member Author

This works but it feels like cheating. 😄 (Note that the totals aren’t expected to go to 100% here because some of the data have undefined sex.)

untitled-45

Plot.plot({
  y: {
    grid: true
  },
  facet: {
    data: penguins,
    x: "species"
  },
  marks: [
    Plot.barY(penguins, Plot.stackY({
      ...Plot.groupX({x: "sex", normalize: "z"}),
      fill: ([d]) => d.sex,
      x: null
    })),
    Plot.ruleY([0])
  ]
})

@Fil
Copy link
Contributor

Fil commented Mar 20, 2021

If what you're saying is that normalize: "z" is difficult to discover, maybe we should rename it to normalize: "series". Other than that I think the code looks good (group the values on sex for each facet, then stack into a single pile).

@mbostock
Copy link
Member Author

No, I think normalize: "z" is fine. I’m saying we also need normalize: "facet" and for Plot.groupX to make x optional (and for Plot.groupY to make y optional, and probably for Plot.group to make x and y both optional).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants