Forum Discussion
Deneb - 3x3 subplot
- 4 years ago
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
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
Thanks for this. It's exactly the structure I was needing to move forward!