Skip to content
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

Note about bar plots with log scales #1039

Closed
wants to merge 1 commit into from

Conversation

tschaub
Copy link

@tschaub tschaub commented Aug 30, 2022

This adds a hint that bars must include an explicit start and end so that the domain doesn't include zero when using log scales.

See #1038.

@Fil
Copy link
Contributor

Fil commented Aug 30, 2022

It's not only about bars—other marks such as rect and area also have an implicit base value = 0.

An alternative would be to write:

A log transform is suitable for comparing orders of magnitude and can only be used when the domain does not include zero—for marks such as areas or bars, which implicitly extend from a zero baseline, this means specifying non-zero start and end values.

On a more philosophical note I'm struggling to know what to recommend in that case, because in general, bar charts typically encode quantities that can be added (and stacked), and addition only works well with a linear scale.

Back to your notebook, I like what you did in the last example with x: {type: 'log', domain: [1e3, 1e7], clamp: true}; using a symlog scale would also work well.

Here are two other approaches I've tried:

  1. transforming the values with a log function:
Plot.plot({
  marks: [
    Plot.barX(data, Plot.mapX(X => X.map(d => Math.log10(d)), {x: "count", y: "letter"}))
  ],
  x: {tickFormat: d => 10**d},
  grid: true
})
  1. using offset to add 1 to every start and end values:
Plot.plot({
  marks: [
    Plot.barX(data, {
      x: "count",
      y: "letter",
      offset: (index, start, end, z) => {
        for (const stack of index) {
          for (const series of stack) {
            for (const i of series) start[i] = 1 + start[i];
          }
        }
      }
    })
  ],
  x: { type: "log" },
  grid: true
})

Note that the offset strategy allows to stack values, but makes it even harder to make sense of the resulting chart, because you basically have to do a reverse mental calculation.

@Fil Fil mentioned this pull request Aug 30, 2022
12 tasks
@Fil
Copy link
Contributor

Fil commented Feb 6, 2023

Revising this, an alternative might be to change the bar section, where it has:

"this is the typical configuration for a vertical bar chart with bars aligned at y = 0"

we could add " (note that this supposes that the y scale is linear, or at the very least can represent 0)."

This would be correct in a sense, but alas I'm not sure it would help anyone figure out what they're doing wrong… I'll close the suggestion for now, because I don't see how we can address this properly—maybe it's more something for a tutorial. More suggestions are still welcome!

@Fil Fil closed this Feb 6, 2023
@tschaub tschaub deleted the log-bar branch February 6, 2023 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants