Search code examples
concatenationlinechartaltairvega-lite

Altair SchemaValidationError: Invalid specification


I have made this chart:

chart

Using this code:

q2 =  alt.Chart(source, width=100, height=100).mark_line().encode(
        y=alt.Y("prob:Q", title = ''),
        x=alt.X("year:O", title = ''),
        row=alt.Row("key1:N", title="Probability of "),
        column=alt.Column("key2:N", title="Given..."),
    )

However I need the "Given..." And "Probability of" to occur for each row, not just once, as well as have the years show up on each graph's x-axis. Here is what it should look like:

chart2

And here is the dataframe I'm working with:

df

I know that this will require some levels of concatenation but I am not sure how to apply that concept to my chart. I have tried this:

charts = []
for key in totest:
    data = source[source['key1'] == key]
    chart = alt.Chart(data).mark_line().encode(
    y=alt.Y("prob:Q", title = ''),
    x=alt.X("year:O", title = ''),
    row=alt.Row("key1:N", axis=alt.Axis(title=['Probability of', key])),
    facet = alt.Facet("key2:N", sort=totest, title = "Given...")
            )
charts.append(chart)
return alt.vconcat(*charts)

But I get this error:

SchemaValidationError: Invalid specification

        altair.vegalite.v4.schema.channels.Row, validating 'additionalProperties'

        Additional properties are not allowed ('axis' was unexpected)
        

alt.VConcatChart(...)

Solution

  • The error is not particularly clear, but the issue is that the Vega-Lite renderer does not support concatenation of faceted charts. I don't know of any good workaround to do what you want to do, aside from displaying multiple charts instead of concatenating them:

    for key in totest:
      data = source[source['key1'] == key]
      chart = alt.Chart(data).mark_line().encode(
        y=alt.Y("prob:Q", title = ''),
        x=alt.X("year:O", title = ''),
        row=alt.Row("key1:N", axis=alt.Axis(title=['Probability of', key])),
        facet = alt.Facet("key2:N", sort=totest, title = "Given...")
      )
      chart.display()