ejain
ejain

Reputation: 3614

Repeating an axis in a faceted Altair chart

Given a simple, faceted chart like:

import altair as alt

data = alt.Data(values = [
    { "category" : "a", "x" : 1, "y" : 2 },
    { "category" : "a", "x" : 2, "y" : 4 },
    { "category" : "b", "x" : 1, "y" : 3 },
    { "category" : "b", "x" : 2, "y" : 5 }
])

alt.Chart(data).mark_point().encode(x = "x:Q", y = "y:Q").facet(
    row = "category:O"
)

How do you have the x axis appear for each subchart, rather than just once at the bottom? This is to improve readability when there are a lot of subcharts...

chart

Upvotes: 3

Views: 1980

Answers (2)

Kaspar Pflugshaupt
Kaspar Pflugshaupt

Reputation: 41

Here's a simple way to repeat the axis, with a drawback:

import altair as alt

data = alt.Data(values = [
    { "category" : "a", "x" : 1, "y" : 2 },
    { "category" : "a", "x" : 2, "y" : 4 },
    { "category" : "b", "x" : 1, "y" : 3 },
    { "category" : "b", "x" : 2, "y" : 5 }
])

alt.Chart(data).mark_point().encode(x = "x:Q", y = "y:Q").facet(
    row = "category:O"
).resolve_scale(x='independent')

But: If the facets do not have identical x-axis ranges, this will also de-couple them! There is, to my knowledge, no simple way of just repeating the axis without making the facets independent. But you can always fix the range to achieve that.

Upvotes: 4

jakevdp
jakevdp

Reputation: 86330

Unfortunately, there's no way to make the x-axis appear in multiple charts when using the row encoding. As a workaround, you can manually vconcat charts based on filtered data:

chart = alt.Chart(data).mark_point().encode(x="x:Q", y="y:Q")

alt.vconcat(
    chart.transform_filter(alt.datum.category == 'a'),
    chart.transform_filter(alt.datum.category == 'b')
)

enter image description here

To avoid writing out the column values manually, you can generate the different subcharts using Python tools; for example, this is equivalent to the above:

df = pd.DataFrame.from_records([
    { "category" : "a", "x" : 1, "y" : 2 },
    { "category" : "a", "x" : 2, "y" : 4 },
    { "category" : "b", "x" : 1, "y" : 3 },
    { "category" : "b", "x" : 2, "y" : 5 }
])

chart = alt.Chart(df).mark_point().encode(x="x:Q", y="y:Q")

alt.vconcat(
    *(chart.transform_filter(alt.datum.category == val)
      for val in df['category'].unique())
)

Upvotes: 5

Related Questions