Search code examples
pythonpython-3.xaltair

How to add second y-axis to the bar chart? Altair


I have a DataFrame:

  EMOJI   PERCENT_TEXT    PERCENT     combined
0  😂         23.1%        23.1       😂 23.1%
1  🥊         5.7%          5.7       🥊 5.7% 
2  👊         3.5%          3.5       👊 3.5%
3  👏         3.0%          3.0       👏 3.0%
4  💪         2.5%          2.5       💪 2.5%
5  🇮🇪          2.4%          2.4        🇮🇪  2.4%

My code is below:

bars = alt.Chart(percentages_df).mark_bar(color='orange').encode(
    alt.X('PERCENT:Q',axis=None),
    alt.Y('combined:N', sort='-x', title=None)
).configure_view(strokeOpacity=0).configure_axis(
    # remove axis line
    grid=False, domain=False,ticks=False
)

enter image description here

But the chart I created is not what I expected.

I want to create a bar chart by Altair with two y-axis labels, like this: enter image description here

Should I use layer to generate this chart? If so, how to generate layers of two y-axis labels? If not, what should I use to generate it? Thanks!


Solution

  • I don't know of any easy way to create two distinct sets of axis labels, but you can roughly accomplish the alignment you want by adjusting axis label properties.

    I also changed the chart to create the combined label using a transform:

    import pandas as pd
    import altair as alt
    
    percentages_df = pd.DataFrame({
      'EMOJI': ['😂', '🥊', '👊', '👏', '💪', '🇮🇪'],
      'PERCENT': [23.1, 5.7, 3.5, 3.0, 2.5, 2.4]
    })
    
    alt.Chart(percentages_df).transform_calculate(
        combined = alt.datum.EMOJI + '    ' + alt.datum.PERCENT + '%'
    ).mark_bar(color='orange').encode(
        alt.X('PERCENT:Q',axis=None),
        alt.Y('combined:N', sort='-x', title=None,
              axis=alt.Axis(labelAlign='left', labelPadding=6))
    ).configure_view(strokeOpacity=0).configure_axis(
        # remove axis line
        grid=False, domain=False,ticks=False
    )
    

    chart

    Another option is to concatenate two charts, one of which has no x-encoding:

    import pandas as pd
    import altair as alt
    
    percentages_df = pd.DataFrame({
      'EMOJI': ['😂', '🥊', '👊', '👏', '💪', '🇮🇪'],
      'PERCENT': [23.1, 5.7, 3.5, 3.0, 2.5, 2.4]
    })
    
    right = alt.Chart(percentages_df).mark_bar(color='orange').encode(
        alt.X('PERCENT:Q',axis=None),
        alt.Y('PERCENT:N', sort='-x', title=None)
    )
    
    left = alt.Chart(percentages_df).mark_text().encode(
        alt.Y('EMOJI:N', sort=alt.EncodingSortField('PERCENT', order="descending"), title=None)
    )
    
    alt.hconcat(
        left, right
    ).configure_view(strokeOpacity=0).configure_axis(
        # remove axis line
        grid=False, domain=False,ticks=False
    )
    

    chart 2