Diverging Stacked Bar Chart in Plot

I am interested in creating a diverging stacked bar chart to visualize some survey data. I have attached a sample notebook with where I am at so far.

What I would like to do is transform each bar to be aligned such that the “Neutral” category is centered on the x-axis about zero. I am using the Robbins & Heiberger paper as a reference.

I don’t know if this is an operation that would be done in the Plot specification, or if I should transform the data first, and then plot afterward.

Each bar would need to be moved to the left by the sum of “Strongly Disagree”, “Disagree” and half of “Neutral”.

Anyways, just looking for some advice and wondering if anyone here has done something similar before.

Thanks for your help,
-Eitan

I can’t think of an easy way to center the neutral category… but you can create diverging stacked bar charts by returning a negative value (e.g., a negative count) from the group reducer. For example:

Plot.plot({
  facet: {
    data: data,
    y: "Question"
  },
  color: {
    legend: true,
    domain: scale,
    scheme: "RdBu"
  },
  marks: [
    Plot.barX(
      data,
      Plot.groupZ(
        {
          x(D) {
            switch (D[0]) {
              case "Strongly Disagree":
              case "Disagree":
                return -D.length;
              case "Agree":
              case "Strongly Agree":
              default:
                return D.length;
            }
          }
        },
        {
          x: "Response",
          fill: "Response",
          order: [
            "Disagree",
            "Strongly Disagree",
            "Neutral",
            "Agree",
            "Strongly Agree"
          ]
        }
      )
    )
  ]
})

Note that the stack order is reversed with the negative values, hence the reordered order option.

1 Like

This is a common requirement, unfortunately quite difficult to address with the current stacking options. Here’s a suggestion: Diverging Stacked Bar Chart Help / Fil / Observable ; but it’s probably worth opening an issue to make this feasible as a stacking option?

2 Likes

Nice technique, @Fil.

I’ve completely rewritten the notebook, with details for a better answer to this issue


EDIT: now working towards an even better resolution.