LogZ
LogZ

Reputation: 164

Altair grouped bar chart with different categories per group

I am trying to make an altair grouped bar chart where each group has different categories. The standard grouped bar chart plotting code produces plots where each plot's x-axis contains all categories, including those unused by a certain group. The following code and produced plot illustrates the problem:

import altair as alt
import pandas as pd

# Sample data
data = {
    'Group': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'],
    'Category': ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3'],
    'Value': [10, 15, 7, 8, 12, 18, 12, 10, 9]
}

df = pd.DataFrame(data)

# Create the grouped bar chart
chart = alt.Chart(df).mark_bar().encode(
    x=alt.X('Category:N', title='Category'),
    y=alt.Y('Value:Q', title='Value'),
    column=alt.Column('Group:N', title='Group')
)

chart

Grouped bar chart with white space for unused categories

Is there an easy way to remove categories that have no data for a specific group? That is, the above chart should have 3 facets. The first facet should contain only bars and x-axis for {A1, A2, A3}, the second and third should contain the B and C categories, respectively. If there is no easy way to do this, I see two possible approaches:

  1. Manually delete categories from each facet that do not contain data in a group. How do I do this?

  2. Create individual bar charts and then concatenate them horizontally. I would want the plots to share the same scale (and other properties like colors that I will add later) and also have "Group" labels for each of the subplots. Is there an easy way to do this that does not require a lot of boilerplate (like manually computing range of data, adding group titles to each subplot, etc.)?

Upvotes: 1

Views: 35

Answers (1)

kgoodrick
kgoodrick

Reputation: 883

Altair has the ability to resolve each axes' scale independently:

working image

import altair as alt
import pandas as pd

# Sample data
data = {
    'Group': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'],
    'Category': ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3'],
    'Value': [10, 15, 7, 8, 12, 18, 12, 10, 9]
}

df = pd.DataFrame(data)

# Create the grouped bar chart
chart = alt.Chart(df).mark_bar().encode(
    x=alt.X('Category:N', title='Category'),
    y=alt.Y('Value:Q', title='Value'),
    column=alt.Column('Group:N', title='Group')
)

chart.resolve_scale(x='independent')

Upvotes: 1

Related Questions