Public
Edited
Oct 27, 2023
Insert cell
Insert cell
Plot.plot({
x: {tickFormat: Math.abs},
color: {domain: likert.order, scheme: "RdBu", legend: true},
marks: [
Plot.barX(
survey,
Plot.groupZ({x: "count"}, {fy: "Question", fill: "Response", ...likert})
),
Plot.ruleX([0])
]
})
Insert cell
likert = Likert([
["Strongly Disagree", -1],
["Disagree", -1],
["Neutral", 0],
["Agree", 1],
["Strongly Agree", 1]
])
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
x: { tickFormat: Math.abs, label: "# of answers" },
y: { tickSize: 0 },
color: {
legend: true,
domain: [
"Strongly Disagree",
"Disagree",
"Neutral",
"Agree",
"Strongly Agree"
],
scheme: "RdBu"
},
marks: [
Plot.barX(
survey,
Plot.groupY(
{ x: "count" },
{
fill: "Response",
order: [
"Strongly Disagree",
"Disagree",
"Neutral",
"Agree",
"Strongly Agree"
],
y: "Question"
}
)
)
]
})
Insert cell
Insert cell
Insert cell
sign = (label) => label.match(/neutral/i) ? 0 : label.match(/disagree/i) ? -1 : 1
Insert cell
Plot.plot({
color: {
domain: [
"Strongly Disagree",
"Disagree",
"Neutral",
"Agree",
"Strongly Agree"
],
scheme: "RdBu"
},
marks: [
Plot.barX(
survey,
Plot.groupY(
{ x: (d) => d.length * sign(d[0].Response) },
{
fill: "Response",
order: [
"Strongly Disagree",
"Disagree",
"Neutral",
"Agree",
"Strongly Agree"
],
y: "Question"
}
)
)
]
})
Insert cell
survey((d) => d.length)
Insert cell
survey
Insert cell
Insert cell
Insert cell
Insert cell
{
const { order, offset } = Likert([
["Strongly Disagree", -1],
["Disagree", -1],
["Neutral", 0],
["Agree", 1],
["Strongly Agree", 1]
]);

return Plot.plot({
x: normalize
? { tickFormat: "%", label: "answers (%)" }
: { tickFormat: Math.abs, label: "# of answers" },
y: { tickSize: 0 },
facet: { data: survey, y: "Question" },
color: { domain: order, scheme: "RdBu" },
marks: [
Plot.barX(
survey,
Plot.groupZ(
{ x: normalize ? "proportion-facet" : "count" },
{
fill: "Response",
stroke: "#777",
strokeWidth: 0.5,
order,
offset
}
)
),
Plot.textX(
survey,
Plot.stackX(
Plot.groupZ(
{ x: normalize ? "proportion-facet" : "count", text: "first" },
{
text: (d) => d.Response.replace(/[^A-Z]/g, ""),
z: "Response",
order,
offset
}
)
)
)
]
});
}
Insert cell
Insert cell
function Likert(responses) {
const map = new Map(responses);
return {
order: Array.from(map.keys()),
offset(I, X1, X2, Z) {
for (const stacks of I) {
for (const stack of stacks) {
const k = d3.sum(stack, (i) => (X2[i] - X1[i]) * (1 - map.get(Z[i]))) / 2;
for (const i of stack) {
X1[i] -= k;
X2[i] -= k;
}
}
}
}
};
}
Insert cell
Insert cell
survey = FileAttachment("survey.json").json()
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more