Altair: alt.Repeat - create a grid of charts

Created on 11 Sep 2018  路  4Comments  路  Source: altair-viz/altair

Hi Jake,

In the docs you have a nice repeating example that I am trying to learn from. But suppose I have a simple dataFrame like this:

df=pd.DataFrame({'year': [1,2,3], 'school 1': [10,20,30], 'school 2': [15,6,25], 'school 3': [120,202,302], 'school 4': [152,6,225]})

and I would like a 2x2 grid where for each chart "year" is on the x axis and each charts show a line for a given school. So basically, one field is held constant. I can accomplish this by doing the following, but is there a better, more "Altair-ic" way to do this?

visualization 19

y1=alt.Chart().mark_line(point=True).encode(
    x='year',
    y='school 1',
)

y2=alt.Chart().mark_line(point=True).encode(
    x='year',
    y='school 2',
)

y3=alt.Chart().mark_line(point=True).encode(
    x='year',
    y='school 3',
)

y4=alt.Chart().mark_line(point=True).encode(
    x='year',
    y='school 4',
)

alt.vconcat((y1|y2), (y3|y4), data=df)

Most helpful comment

For anyone looking for an example until this functionality is in VL/Altair. There are various solutions here and my attempt is the following. Note that the DataFrame in this case has three columns and is in long form (see df.melt)

numcols=3 # specify the number of columns you want 
all_categories=df['Category_Column'].unique() # array of strings to use as your filters and titles

rows=alt.vconcat(data=df)
numrows=int(np.ceil(len(all_categories) / numcols))
pointer=0
for _ in range(numrows):

  row=all_categories[pointer:pointer+numcols]
  cols=alt.hconcat()

  for a_chart in row:

     # add your layers here
     # line chart
     line=alt.Chart().mark_line(point=True).encode(
        x='variable',
        y='value'
     ).transform_filter(datum.Category_Column == a_chart).properties(
        title=a_chart, height=200, width=200)

     # text labels
     text=alt.Chart().mark_text().encode(
        x='variable', 
        y='value'
     ).transform_filter(datum.Category_Column == a_chart)

     both = line + text
     cols |= both

  rows &= cols
  pointer += numcols

rows

visualization 22

All 4 comments

A possible connection to this VL issue

Yep, what you're describing is more or less a wrapped facet, and it's not yet available in Vega-Lite or Altair.

Thanks Jake.

For anyone looking for an example until this functionality is in VL/Altair. There are various solutions here and my attempt is the following. Note that the DataFrame in this case has three columns and is in long form (see df.melt)

numcols=3 # specify the number of columns you want 
all_categories=df['Category_Column'].unique() # array of strings to use as your filters and titles

rows=alt.vconcat(data=df)
numrows=int(np.ceil(len(all_categories) / numcols))
pointer=0
for _ in range(numrows):

  row=all_categories[pointer:pointer+numcols]
  cols=alt.hconcat()

  for a_chart in row:

     # add your layers here
     # line chart
     line=alt.Chart().mark_line(point=True).encode(
        x='variable',
        y='value'
     ).transform_filter(datum.Category_Column == a_chart).properties(
        title=a_chart, height=200, width=200)

     # text labels
     text=alt.Chart().mark_text().encode(
        x='variable', 
        y='value'
     ).transform_filter(datum.Category_Column == a_chart)

     both = line + text
     cols |= both

  rows &= cols
  pointer += numcols

rows

visualization 22

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fischcheng picture fischcheng  路  4Comments

firasm picture firasm  路  3Comments

floringogianu picture floringogianu  路  3Comments

breadbaron picture breadbaron  路  4Comments

DentonGentry picture DentonGentry  路  3Comments