Forum Discussion

Anonymous's avatar
Anonymous
Not applicable
3 years ago
Solved

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: 

CountryAnimalsAmount
Great Britainpigs2
Great Britaincows3
Great Britainsheep6
United Statespigs6
United Statescows7
United Statessheep1
  • 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-p's avatar
    dm-p
    Super 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

    • Anonymous's avatar
      Anonymous
      Not 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 🙂