Forum Discussion

patBear's avatar
patBear
Helper I
4 years ago
Solved

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. [Even...
  • dm-p's avatar
    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