'''
US Population Pyramid Over Time
===============================
A population pyramid shows the distribution of age groups within a population.
It uses a slider widget that is bound to the year to visualize the age
distribution over time.
'''
# category: case studies
import altair as alt
from altair.expr import datum, if_
from vega_datasets import data

pop = data.population.url

slider = alt.binding_range(min=1850, max=2000, step=10)
select_year = alt.selection_single(name='year', fields=['year'], bind=slider)

base = alt.Chart(pop).add_selection(
    select_year
).transform_filter(
    select_year
).transform_calculate(
    gender=if_(datum.sex == 1, 'Male', 'Female')
)

title = alt.Axis(title='population')
color_scale = alt.Scale(domain=['Male', 'Female'],
                        range=['#1f77b4', '#e377c2'])

left = base.transform_filter(
    datum.gender == 'Female'
).encode(
    y=alt.X('age:O', axis=None),
    x=alt.X('sum(people):Q', axis=title, sort=alt.SortOrder('descending')),
    color=alt.Color('gender:N', scale=color_scale, legend=None)
).mark_bar().properties(title='Female')

middle = base.encode(
    y=alt.X('age:O', axis=None),
    text=alt.Text('age:Q'),
).mark_text().properties(width=20)

right = base.transform_filter(
    datum.gender == 'Male'
).encode(
    y=alt.X('age:O', axis=None),
    x=alt.X('sum(people):Q', axis=title),
    color=alt.Color('gender:N', scale=color_scale, legend=None)
).mark_bar().properties(title='Male')

left | middle | right
[((395, 441), 'altair.binding_range', 'alt.binding_range', ([], {'min': '(1850)', 'max': '(2000)', 'step': '(10)'}), '(min=1850, max=2000, step=10)\n', (412, 441), True, 'import altair as alt\n'), ((456, 519), 'altair.selection_single', 'alt.selection_single', ([], {'name': '"""year"""', 'fields': "['year']", 'bind': 'slider'}), "(name='year', fields=['year'], bind=slider)\n", (476, 519), True, 'import altair as alt\n'), ((693, 721), 'altair.Axis', 'alt.Axis', ([], {'title': '"""population"""'}), "(title='population')\n", (701, 721), True, 'import altair as alt\n'), ((736, 802), 'altair.Scale', 'alt.Scale', ([], {'domain': "['Male', 'Female']", 'range': "['#1f77b4', '#e377c2']"}), "(domain=['Male', 'Female'], range=['#1f77b4', '#e377c2'])\n", (745, 802), True, 'import altair as alt\n'), ((644, 681), 'altair.expr.if_', 'if_', (['(datum.sex == 1)', '"""Male"""', '"""Female"""'], {}), "(datum.sex == 1, 'Male', 'Female')\n", (647, 681), False, 'from altair.expr import datum, if_\n'), ((528, 542), 'altair.Chart', 'alt.Chart', (['pop'], {}), '(pop)\n', (537, 542), True, 'import altair as alt\n'), ((903, 928), 'altair.X', 'alt.X', (['"""age:O"""'], {'axis': 'None'}), "('age:O', axis=None)\n", (908, 928), True, 'import altair as alt\n'), ((1016, 1069), 'altair.Color', 'alt.Color', (['"""gender:N"""'], {'scale': 'color_scale', 'legend': 'None'}), "('gender:N', scale=color_scale, legend=None)\n", (1025, 1069), True, 'import altair as alt\n'), ((1139, 1164), 'altair.X', 'alt.X', (['"""age:O"""'], {'axis': 'None'}), "('age:O', axis=None)\n", (1144, 1164), True, 'import altair as alt\n'), ((1175, 1192), 'altair.Text', 'alt.Text', (['"""age:Q"""'], {}), "('age:Q')\n", (1183, 1192), True, 'import altair as alt\n'), ((1304, 1329), 'altair.X', 'alt.X', (['"""age:O"""'], {'axis': 'None'}), "('age:O', axis=None)\n", (1309, 1329), True, 'import altair as alt\n'), ((1337, 1371), 'altair.X', 'alt.X', (['"""sum(people):Q"""'], {'axis': 'title'}), "('sum(people):Q', axis=title)\n", (1342, 1371), True, 'import altair as alt\n'), ((1383, 1436), 'altair.Color', 'alt.Color', (['"""gender:N"""'], {'scale': 'color_scale', 'legend': 'None'}), "('gender:N', scale=color_scale, legend=None)\n", (1392, 1436), True, 'import altair as alt\n'), ((976, 1003), 'altair.SortOrder', 'alt.SortOrder', (['"""descending"""'], {}), "('descending')\n", (989, 1003), True, 'import altair as alt\n')]