bar-chartaxis-labelsvega-litegrouped-bar-chart

Nested axis labels for grouped bar chart in Vega Lite


I'm building a grouped bar chart using Vega-Lite. Every data point has a count, a sample and an fdr value. The bars are grouped per sample and in these groups, I want one bar per fdr-value. I was able to accomplish all of this using the following specification (click here for a version in the Vega editor):

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {
    "values": [
      {"count": 87, "organism": "Thaliana", "sample": "S01", "fdr": "0.1%"},
      {"count": 231, "organism": "Spider", "sample": "S01", "fdr": "0.1%"},
      {"count": 40, "organism": "Thaliana", "sample": "S01", "fdr": "1%"},
      {"count": 560, "organism": "Spider", "sample": "S01", "fdr": "1%"},
      {"count": 11.33, "organism": "Thaliana", "sample": "S02", "fdr": "0.1%"},
      {"count": 88.67, "organism": "Spider", "sample": "S02", "fdr": "0.1%"},
      {"count": 70, "organism": "Thaliana", "sample": "S02", "fdr": "1%"},
      {"count": 30, "organism": "Spider", "sample": "S02", "fdr": "1%"}
    ]
  },
  "width": "container",
  "layer": [
    {
      "mark": "bar",
      "encoding": {
        "x": {
          "aggregate": "sum",
          "field": "count",
          "stack": "normalize",
          "title": "Distribution (%)",
          "sort": "descending",
          "axis": {"labelFontSize": 14, "titleFontSize": 20}
        },
        "y": {
          "field": "sample",
          "title": "Sample name",
          "axis": {
            "labelFontSize": 14,
            "titleFontSize": 20,
            "labelLimit": 500,
            "labelExpr": "datum.label"
          }
        },
        "yOffset": {"field": "fdr", "scale": {"paddingInner": 0.1}},
        "color": {"field": "organism", "legend": {"title": "Species"}}
      }
    }
  ],
  "config": {
    "legend": {
      "orient": "bottom",
      "direction": "vertical",
      "columns": 4,
      "labelFontSize": 14,
      "titleFontSize": 16,
      "labelLimit": 250,
      "symbolSize": 150
    }
  }
}

A screenshot of the current visualization:

Example of my grouped bar chart thus far.

Now, the issue that I have is that I also want to add a label showing the fdr-value per bar (since every bar only corresponds to one fdr). But I cannot manage to get this working because the yOffset channel doesn't support its own axis.

Any ideas on how I can accomplish this?

EDIT: This is an example of approximately what it is that I want to achieve:

enter image description here


Solution

  • Do you mean like this? enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {
        "values": [
          {"count": 87, "organism": "Thaliana", "sample": "S01", "fdr": "0.1%"},
          {"count": 231, "organism": "Spider", "sample": "S01", "fdr": "0.1%"},
          {"count": 40, "organism": "Thaliana", "sample": "S01", "fdr": "1%"},
          {"count": 560, "organism": "Spider", "sample": "S01", "fdr": "1%"},
          {"count": 11.33, "organism": "Thaliana", "sample": "S02", "fdr": "0.1%"},
          {"count": 88.67, "organism": "Spider", "sample": "S02", "fdr": "0.1%"},
          {"count": 70, "organism": "Thaliana", "sample": "S02", "fdr": "1%"},
          {"count": 30, "organism": "Spider", "sample": "S02", "fdr": "1%"}
        ]
      },
      "width": "container",
      "encoding": {
        "y": {
          "field": "sample",
          "title": "Sample name",
          "axis": {
            "labelFontSize": 14,
            "titleFontSize": 20,
            "labelLimit": 500,
            "labelExpr": "datum.label"
          }
        },
        "yOffset": {"field": "fdr", "scale": {"paddingInner": 0.1}}
      },
      "layer": [
        {
          "mark": "bar",
          "encoding": {
            "x": {
              "aggregate": "sum",
              "field": "count",
              "stack": "normalize",
              "title": "Distribution (%)",
              "sort": "descending",
              "axis": {"labelFontSize": 14, "titleFontSize": 20}
            },
            "color": {"field": "organism", "legend": {"title": "Species"}}
          }
        },
        {
          "mark": {"type": "text", "opacity": 0.9},
          "encoding": {
            "x": {
              "aggregate": "sum",
              "field": "count",
              "sort": "descending",
              "stack": "normalize",
              "bandPosition": 0.5
            },
            "text": {"field": "fdr"},
            "detail": {"field": "organism"},
            "color": {"value": "white"}
          }
        }
      ],
      "config": {
        "legend": {
          "orient": "bottom",
          "direction": "vertical",
          "columns": 4,
          "labelFontSize": 14,
          "titleFontSize": 16,
          "labelLimit": 250,
          "symbolSize": 150
        }
      }
    }
    

    Edit:

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {
        "values": [
          {"count": 87, "organism": "Thaliana", "sample": "S01", "fdr": "0.1%"},
          {"count": 231, "organism": "Spider", "sample": "S01", "fdr": "0.1%"},
          {"count": 40, "organism": "Thaliana", "sample": "S01", "fdr": "1%"},
          {"count": 560, "organism": "Spider", "sample": "S01", "fdr": "1%"},
          {"count": 11.33, "organism": "Thaliana", "sample": "S02", "fdr": "0.1%"},
          {"count": 88.67, "organism": "Spider", "sample": "S02", "fdr": "0.1%"},
          {"count": 70, "organism": "Thaliana", "sample": "S02", "fdr": "1%"},
          {"count": 30, "organism": "Spider", "sample": "S02", "fdr": "1%"}
        ]
      },
      "width": 500,
      "mark": "bar",
      "encoding": {
       
       "row": {"field": "sample", "header":{"labelFontSize":20, "labelFontWeight":"bold", "labelAngle": 0, "labelPadding":-30, "title":"Sample Name", "titleFontSize":20}},
        "y": {
          "field": "fdr",
           "axis": {"labelFontSize": 12, "titleFontSize": 0, "labelExpr": "'FDR ' + datum.value", "labelAlign":"left", "labelPadding":60}
        },
       
        "x": {
          "aggregate": "sum",
          "type": "quantitative",
          "field": "count",
          "stack": "normalize",
          "title": "Distribution (%)",
          "sort": "descending",
          "axis": {"labelFontSize": 14, "titleFontSize": 20}
           },
        "color": {"field": "organism", "legend": {"title": "Species"}}
      },
      "config": {
        "legend": {
          "orient": "bottom",
          "direction": "vertical",
          "columns": 4,
          "labelFontSize": 14,
          "titleFontSize": 16,
          "symbolSize": 150
        }
      }
    }