'How to create a grouped bar chart in Altair?

How does one create a grouped bar chart in Altair? I'm trying the following but it is just producing two graphs side by side.

Chart(data).mark_bar().encode(
   column='Gender',
   x='Genre',
   y='Rating',
   color='Gender'
)

This is the image produce



Solution 1:[1]

Example of group bar chart

I show a simplified example of Grouped Bar Chart from Altair's documentation. You can also see the full documentation here.

Basically, you have to specify x-axis Gender (F or M in each subplot), y-axis as Rating and Genre as Column.

from altair import *
import pandas as pd

# create dataframe
df = pd.DataFrame([['Action', 5, 'F'], 
                   ['Crime', 10, 'F'], 
                   ['Action', 3, 'M'], 
                   ['Crime', 9, 'M']], 
                  columns=['Genre', 'Rating', 'Gender'])

chart = Chart(df).mark_bar().encode(
   column=Column('Genre'),
   x=X('Gender'),
   y=Y('Rating'),
   color=Color('Gender', scale=Scale(range=['#EA98D2', '#659CCA']))
).configure_facet_cell(
    strokeWidth=0.0,
)

chart.display() # will show the plot

The bar chart will look like following

image

Adding Axis parameters

You only have to follow Axis parameters in documentation to make the plot looks prettier:

chart = Chart(df).mark_bar().encode(
   column=Column('Genre', 
                 axis=Axis(axisWidth=1.0, offset=-8.0, orient='bottom'),
                 scale=Scale(padding=4.0)),
   x=X('Gender', axis=False),
   y=Y('Rating', axis=Axis(grid=False)),
   color=Color('Gender', scale=Scale(range=['#EA98D2', '#659CCA']))
).configure_facet_cell(
    strokeWidth=0.0,
)

chart.display()

Imgur

Solution 2:[2]

If you try the accepted answers on newer version of Altair (since 4.2.0). You will notice that it doesn't work. Some of the API has changed, so to get the same results in Altair 4.2.0 you can use the approach posted in my answer to Grouped bar chart in newer versions of altair (>= 4.2.0). For the development version of Altair (which will probably be released as 5.0), this has become easier to achieve since you can use the xOffset encoding like this without the need to facet your charts:

import altair as alt
import pandas as pd

df = pd.DataFrame([['Action', 5, 'F'], 
                   ['Crime', 10, 'F'], 
                   ['Action', 3, 'M'], 
                   ['Crime', 9, 'M']], 
                  columns=['Genre', 'Rating', 'Gender'])

chart = alt.Chart(df).mark_bar().encode(
   x=alt.X('Genre', axis=alt.Axis(labelAngle=0)),
   xOffset='Gender',
   y=alt.Y('Rating', axis=alt.Axis(grid=False)),
   color='Gender'
).configure_view(
    stroke=None,
)

chart

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 joe
Solution 2 joelostblom