Forum Discussion
Deneb - 3x3 subplot
I'm wanting to create a chart (I'm calling it a 3x3 subplot, but this may not be the correct name) in Deneb: for each categorical x and y value, I want a stacked bar chart of the project names. [Eventually, colors will be added from a z value, highlighting based on group or tier, etc.] I'm using this sample data
and the code below. Currently, the bars are layered rather than stacked. I think I need to incorporate this transformation (measure cnt = COUNT('Table'[name]))
"transform": [
{
"stack": "cnt",
"as": ["ymin", "ymax"],
"groupby": ["x", "y"]
}
]but I'm not sure how/where to insert it into the code below.
{
"data": {"name": "dataset"},
"layer": [
{
"mark": {
"type": "bar",
"stroke": "black",
"strokeWidth": 1,
"tooltip": true
}
},
{
"mark": "text",
"encoding": {
"text": {
"field": "Name",
"type": "nominal"
}
}
}
],
"encoding": {
"x": {
"field": "x",
"type": "nominal",
"scale": {
"domain": ["low", "med", "high"]
},
"axis": {
"title": "X Level",
"labelAngle": 0
}
},
"y": {
"field": "y",
"type": "nominal",
"scale": {
"domain": ["high", "med", "low"]
},
"axis": {"title": "Y Level"}
}
}
}To be clear, I'm aiming for this sort of chart where names have been removed.
Hi patBear,
This should be achievable with a stack transform at the top-level, as you have guessed. To make the stack work better, I've added a window / row_number transform beforehand to group and sort each square by z:
"transform": [ { "window": [ { "op": "row_number", "as": "group_row_number" } ], "groupby": ["x", "y"], "sort": [{"field": "z"}] }, { "stack": "group_row_number", "groupby": ["x", "y"], "sort": [{"field": "z"}], "as": ["y1", "y2"] } ]This has the effect of assigning a sequence to each row as follows:
Name group_row_number AA 2 BB 1 CC 1 DD 1 EE 2 FF 1 GG 2 HH 1 We then use the same group approach in the stack, and use the group_row_number as the field to stack on.
Once this is done, I just need to use a yOffset in the encoding with the generated y1 field:
"yOffset": { "field": "y1", "scale": {"reverse": true} }One thing I've done is reverse the scale so that marks are drawn from the bottom of each square.
The resulting visual looks as follows:
For completeness, here's the full spec:
{ "data": {"name": "dataset"}, "transform": [ { "window": [ { "op": "row_number", "as": "group_row_number" } ], "groupby": ["x", "y"], "sort": [{"field": "z"}] }, { "stack": "group_row_number", "groupby": ["x", "y"], "sort": [{"field": "z"}], "as": ["y1", "y2"] } ], "layer": [ { "mark": { "type": "bar", "stroke": "black", "strokeWidth": 1, "tooltip": true } }, { "mark": "text", "encoding": { "text": { "field": "Name", "type": "nominal" } } } ], "encoding": { "x": { "field": "x", "type": "nominal", "scale": { "domain": ["low", "med", "high"] }, "axis": { "title": "X Level", "labelAngle": 0 } }, "y": { "field": "y", "type": "nominal", "scale": { "domain": ["high", "med", "low"] }, "axis": {"title": "Y Level"} }, "yOffset": { "field": "y1", "scale": {"reverse": true} } } }Hopefully this is what you're expecting, but should be possible to tweak to your liking if not.
Good luck (and thanks for considering Deneb)!
Daniel
2 Replies
- dm-pSuper User
Hi patBear,
This should be achievable with a stack transform at the top-level, as you have guessed. To make the stack work better, I've added a window / row_number transform beforehand to group and sort each square by z:
"transform": [ { "window": [ { "op": "row_number", "as": "group_row_number" } ], "groupby": ["x", "y"], "sort": [{"field": "z"}] }, { "stack": "group_row_number", "groupby": ["x", "y"], "sort": [{"field": "z"}], "as": ["y1", "y2"] } ]This has the effect of assigning a sequence to each row as follows:
Name group_row_number AA 2 BB 1 CC 1 DD 1 EE 2 FF 1 GG 2 HH 1 We then use the same group approach in the stack, and use the group_row_number as the field to stack on.
Once this is done, I just need to use a yOffset in the encoding with the generated y1 field:
"yOffset": { "field": "y1", "scale": {"reverse": true} }One thing I've done is reverse the scale so that marks are drawn from the bottom of each square.
The resulting visual looks as follows:
For completeness, here's the full spec:
{ "data": {"name": "dataset"}, "transform": [ { "window": [ { "op": "row_number", "as": "group_row_number" } ], "groupby": ["x", "y"], "sort": [{"field": "z"}] }, { "stack": "group_row_number", "groupby": ["x", "y"], "sort": [{"field": "z"}], "as": ["y1", "y2"] } ], "layer": [ { "mark": { "type": "bar", "stroke": "black", "strokeWidth": 1, "tooltip": true } }, { "mark": "text", "encoding": { "text": { "field": "Name", "type": "nominal" } } } ], "encoding": { "x": { "field": "x", "type": "nominal", "scale": { "domain": ["low", "med", "high"] }, "axis": { "title": "X Level", "labelAngle": 0 } }, "y": { "field": "y", "type": "nominal", "scale": { "domain": ["high", "med", "low"] }, "axis": {"title": "Y Level"} }, "yOffset": { "field": "y1", "scale": {"reverse": true} } } }Hopefully this is what you're expecting, but should be possible to tweak to your liking if not.
Good luck (and thanks for considering Deneb)!
Daniel
- patBearHelper I
Thanks for this. It's exactly the structure I was needing to move forward!