1

I´m trying to adopt a Population Pyramid code from https://vega.github.io/vega-lite/examples/concat_population_pyramid.html

In this code the limits of the x axis for male / female are evaluated separatly. Thus max. values for the x axis in both plots differ, which sometimes give an wrong impression of the distribution.

I´m trying to set both axis to the same max value ig the max value of the male/female dataset dynamically, because in my context I`m filtering the dataset via slicers.

current situation how it should look like

I´ve tried to use joinaggregate and use the evaluated parameter to scale :

"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "A population pyramid for the US in 2000.",
"data": { "url": "data/population.json"},
"transform": [
  {"filter": "datum.year == 2000"},
  {"calculate": "datum.sex == 2 ? 'Female' : 'Male'", "as": "gender"},
 { "joinaggregate": 
       [{
          "op": "sum",
          "field": "people",
          "as": "MaxVal"
       }]
      }
],

and used it in

"encoding": {
  "y": {
    "field": "age", "title": null,
    "axis": null, "sort": "descending"
  },
  "x": {
    "aggregate": "sum", "field": "people",
    "title": "population",
    "axis": {"format": "s"},
    "scale": {"domain": [0, "MaxVal"]},

  },

but it did´n work. the "domain" or domainMax must be a calculated value, not a constant.

Code:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "description": "A population pyramid for the US in 2000.",
  "data": { "url": "data/population.json"},
  "transform": [
    {"filter": "datum.year == 2000"},
    {"calculate": "datum.sex == 2 ? 'Female' : 'Male'", "as": "gender"},
     { "joinaggregate": 
       [{
          "op": "sum",
          "field": "people",
          "as": "MaxVal"
       }]
      }
  ],
  "spacing": 0,
  "hconcat": [{
    "transform": [{
      "filter": {"field": "gender", "equal": "Female"}
    }],
    "title": "Female",
    "mark": "bar",
    "encoding": {
      "y": {
        "field": "age", "axis": null, "sort": "descending"
      },
      "x": {
        "aggregate": "sum", "field": "people",
        "title": "population",
        "axis": {"format": "s"},
        "scale": {"domain": [0, "MaxVal"]},
        "sort": "descending"
      },
      "color": {
        "field": "gender",
        "scale": {"range": ["#675193", "#ca8861"]},
        "legend": null
      }
    }
  }, {
    "width": 20,
    "view": {"stroke": null},
    "mark": {
      "type": "text",
      "align": "center"
    },
    "encoding": {
      "y": {"field": "age", "type": "ordinal", "axis": null, "sort": "descending"},
      "text": {"field": "age", "type": "quantitative"}
    }
  }, {
    "transform": [{
      "filter": {"field": "gender", "equal": "Male"}
    }],
    "title": "Male",
    "mark": "bar",
    "encoding": {
      "y": {
        "field": "age", "title": null,
        "axis": null, "sort": "descending"
      },
      "x": {
        "aggregate": "sum", "field": "people",
        "title": "population",
        "axis": {"format": "s"},
        "scale": {"domain": [0, "MaxVal"]}
      },
      "color": {
        "field": "gender",
        "legend": null
      }
    }
  }],
  "config": {
    "view": {"stroke": null},
    "axis": {"grid": false}
  }
}
Davide Bacci
  • 16,647
  • 3
  • 10
  • 36
NaHolla
  • 83
  • 5

1 Answers1

1

Set your scale to the following:

"scale": {"domainMax":{"expr":"data('source_0')[0].MaxVal"}},

However, your MaxVal calculation is the sum of all figures so probably not what you want but that is a different question.

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "description": "A population pyramid for the US in 2000.",
  "data": {"url": "data/population.json"},
  "transform": [
    {"filter": "datum.year == 2000"},
    {"calculate": "datum.sex == 2 ? 'Female' : 'Male'", "as": "gender"},
    {"joinaggregate": [{"op": "sum", "field": "people", "as": "MaxVal"}]}
  ],
  "spacing": 0,
  "hconcat": [
    {
      "transform": [{"filter": {"field": "gender", "equal": "Female"}}],
      "title": "Female",
      "mark": "bar",
      "encoding": {
        "y": {"field": "age", "axis": null, "sort": "descending"},
        "x": {
          "aggregate": "sum",
          "field": "people",
          "title": "population",
          "axis": {"format": "s"},
          "scale": {"domainMax":{"expr":"data('source_0')[0].MaxVal"}},
          "sort": "descending"
        },
        "color": {
          "field": "gender",
          "scale": {"range": ["#675193", "#ca8861"]},
          "legend": null
        }
      }
    },
    {
      "width": 20,
      "view": {"stroke": null},
      "mark": {"type": "text", "align": "center"},
      "encoding": {
        "y": {
          "field": "age",
          "type": "ordinal",
          "axis": null,
          "sort": "descending"
        },
        "text": {"field": "age", "type": "quantitative"}
      }
    },
    {
      "transform": [{"filter": {"field": "gender", "equal": "Male"}}],
      "title": "Male",
      "mark": "bar",
      "encoding": {
        "y": {
          "field": "age",
          "title": null,
          "axis": null,
          "sort": "descending"
        },
        "x": {
          "aggregate": "sum",
          "field": "people",
          "title": "population",
          "axis": {"format": "s"},
          "scale": {"domainMax":{"expr":"data('source_0')[0].MaxVal"}}
        },
        "color": {"field": "gender", "legend": null}
      }
    }
  ],
  "config": {"view": {"stroke": null}, "axis": {"grid": false}}
}
Davide Bacci
  • 16,647
  • 3
  • 10
  • 36
  • thanks, I see what you mean: Is there any way to calculate the max from female/male? – NaHolla Jul 13 '23 at 08:56
  • Add another question and either myself or someone else will answer. I think you may need to approach this differently as you need the max bin value. – Davide Bacci Jul 13 '23 at 09:18