Forum Discussion
Deneb visual
Hi everyone,
I have the following Deneb code:
{ "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"config": {
"view": {
"stroke": ""
}
},
"width": 220,
"height": 55,
"data": {
"name": "dataset"
},
"transform": [
{
"calculate": "{'cows': '🐄', 'pigs': '🐖', 'sheep': '🐏'}[datum['Animals']]",
"as": "emoji"
},
{
"window": [
{
"op": "rank",
"as": "rank"
}
],
"groupby": ["Country", "Animals"]
}
],
"mark": {
"type": "text",
"baseline": "middle"
},
"encoding": {
"x": {
"field": "Amount",
"type": "ordinal",
"axis": true
},
"y": {
"field": "Animals",
"aggregate": "null",
"type": "nominal",
"axis": null,
"sort": null
},
"row": {
"field": "Country",
"header": {
"title": ""
}
},
"text": {
"field": "emoji",
"type": "nominal"
},
"size": {
"value": 20
}
}
}
It does show the animal under the right amount (Great Britain and sheep; it is shown in under 6 in the x-axis). But I want to show 6 sheep. And this for every animal in the two countries. In which way should the code be changed to make this visible?
I hope someone can help me with this.
The table is this:
| Country | Animals | Amount |
| Great Britain | pigs | 2 |
| Great Britain | cows | 3 |
| Great Britain | sheep | 6 |
| United States | pigs | 6 |
| United States | cows | 7 |
| United States | sheep | 1 |
Hi Anonymous,
Looks like you're trying to replicate the Isotype Dot Plot with Emoji example? In this case the dataset has the necessary rows to generate the marks. If you're working with aggregated data, you'll need to make a couple of changes to add the rows during the transform phase. This can be done as follows:
Step 1 - Calculated column with sequence based on Amount
Use a calculate transform and a sequence expression to create an array of values from 1 to Amount, e.g.:
{ ... "transform": [ { "calculate": "{'cows': '🐄', 'pigs': '🐖', 'sheep': '🐏'}[datum['Animals']]", "as": "emoji" }, { "calculate": "sequence(1, datum['Amount'] + 1, 1)", "as": "animal_row" } ], ... }
After this step Vega-Lite will create a new data stream called data_0, which will look similar to the following:Step 2 - Flatten the array to create n rows per group
Now, we'll use the flatten transform to turn this into additional rows for the marks, e.g.:
{ ... "transform": [ { "calculate": "{'cows': '🐄', 'pigs': '🐖', 'sheep': '🐏'}[datum['Animals']]", "as": "emoji" }, { "calculate": "sequence(1, datum['Amount'] + 1, 1)", "as": "animal_row" }, { "flatten": ["animal_row"] } ], ... }Your data_0 stream will now have one row per value in the animal_row array:
Note that you won't need the rank transform, as the previous steps create the sequence per group that was being done in the example.
Step 3 - Encoding changes
Change the x encoding channel to use the animal_row field, e.g.:
{ ... "encoding": { "x": { "field": "animal_row", "type": "ordinal", "axis": null }, ... } }
The rendered visual should look similar to the following:Complete recipe
Here's the whole spec (with some of the parts that caused warnings removed also):
{ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "config": {"view": {"stroke": ""}}, "width": 220, "height": 80, "data": {"name": "dataset"}, "transform": [ { "calculate": "{'cows': '🐄', 'pigs': '🐖', 'sheep': '🐏'}[datum['Animals']]", "as": "emoji" }, { "calculate": "sequence(1, datum['Amount'] + 1, 1)", "as": "animal_row" }, {"flatten": ["animal_row"]} ], "mark": { "type": "text", "baseline": "middle" }, "encoding": { "x": { "field": "animal_row", "type": "ordinal", "axis": null }, "y": { "field": "Animals", "type": "nominal", "axis": null, "sort": null }, "row": { "field": "Country", "header": {"title": ""} }, "text": { "field": "emoji", "type": "nominal" }, "size": {"value": 20} } }I've also attached a .pbix for you with this in to confirm and/or play with as needed.
Good luck (and thanks for trying Deneb)!
Daniel
2 Replies
- dm-pSuper User
Hi Anonymous,
Looks like you're trying to replicate the Isotype Dot Plot with Emoji example? In this case the dataset has the necessary rows to generate the marks. If you're working with aggregated data, you'll need to make a couple of changes to add the rows during the transform phase. This can be done as follows:
Step 1 - Calculated column with sequence based on Amount
Use a calculate transform and a sequence expression to create an array of values from 1 to Amount, e.g.:
{ ... "transform": [ { "calculate": "{'cows': '🐄', 'pigs': '🐖', 'sheep': '🐏'}[datum['Animals']]", "as": "emoji" }, { "calculate": "sequence(1, datum['Amount'] + 1, 1)", "as": "animal_row" } ], ... }
After this step Vega-Lite will create a new data stream called data_0, which will look similar to the following:Step 2 - Flatten the array to create n rows per group
Now, we'll use the flatten transform to turn this into additional rows for the marks, e.g.:
{ ... "transform": [ { "calculate": "{'cows': '🐄', 'pigs': '🐖', 'sheep': '🐏'}[datum['Animals']]", "as": "emoji" }, { "calculate": "sequence(1, datum['Amount'] + 1, 1)", "as": "animal_row" }, { "flatten": ["animal_row"] } ], ... }Your data_0 stream will now have one row per value in the animal_row array:
Note that you won't need the rank transform, as the previous steps create the sequence per group that was being done in the example.
Step 3 - Encoding changes
Change the x encoding channel to use the animal_row field, e.g.:
{ ... "encoding": { "x": { "field": "animal_row", "type": "ordinal", "axis": null }, ... } }
The rendered visual should look similar to the following:Complete recipe
Here's the whole spec (with some of the parts that caused warnings removed also):
{ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "config": {"view": {"stroke": ""}}, "width": 220, "height": 80, "data": {"name": "dataset"}, "transform": [ { "calculate": "{'cows': '🐄', 'pigs': '🐖', 'sheep': '🐏'}[datum['Animals']]", "as": "emoji" }, { "calculate": "sequence(1, datum['Amount'] + 1, 1)", "as": "animal_row" }, {"flatten": ["animal_row"]} ], "mark": { "type": "text", "baseline": "middle" }, "encoding": { "x": { "field": "animal_row", "type": "ordinal", "axis": null }, "y": { "field": "Animals", "type": "nominal", "axis": null, "sort": null }, "row": { "field": "Country", "header": {"title": ""} }, "text": { "field": "emoji", "type": "nominal" }, "size": {"value": 20} } }I've also attached a .pbix for you with this in to confirm and/or play with as needed.
Good luck (and thanks for trying Deneb)!
Daniel
- AnonymousNot applicable
dm-p
Thank you so much for the extensive explanation! This helps me so much to learn to apply visuals in Deneb. I am really grateful for this 🙂