In ggplot2
, it's easy to create a faceted plot with facets that span both rows and columns. Is there a "slick" way to do this in altair
? facet
documentation
It's possible to have facets plot in a single column,
import altair as alt
from vega_datasets import data
iris = data.iris
chart = alt.Chart(iris).mark_point().encode(
x='petalLength:Q',
y='petalWidth:Q',
color='species:N'
).properties(
width=180,
height=180
).facet(
row='species:N'
)
and in a single row,
chart = alt.Chart(iris).mark_point().encode(
x='petalLength:Q',
y='petalWidth:Q',
color='species:N'
).properties(
width=180,
height=180
).facet(
column='species:N'
)
but often, I just want to plot them in a grid using more than one column/row, i.e. those that line up in a single column/row don't mean anything in particular.
For example, see facet_wrap
from ggplot2
: http://www.cookbook-r.com/Graphs/Facets_(ggplot2)/#facetwrap
I found that doing a concatenation of length greater than two in either direction caused the data to become distorted and fall out of the window. I solved this by recursively breaking up the subplot array into quadrants and doing alternating row and column concatenations. If you don't have this problem, good for you: you can use one of the simpler implementations already posted. But, if you do, I hope this helps.
You can do this by specifying
.repeat()
and therow
andcolumn
list of variables. This is closer to ggplot'sfacet_grid()
thanfacet_wrap()
but the API is very elegant. (See discussion here.) The API is hereWhich produces:
Note that the entire set is interactive in tandem (zoom-in, zoom-out).
Be sure to check out RepeatedCharts and FacetedCharts in the Documentation.
Creating a
facet_wrap()
style grid of plotsIf you want a ribbon of charts laid out one after another (not necessarily mapping a column or row to variables in your data frame) you can do that by wrapping a combination of
hconcat()
andvconcat()
over a list of Altair plots.I am sure there are more elegant ways, but this is how I did it.
Logic used in the code below:
base
Altair charttransform_filter()
to filter your data into multiple subplots-
to produce:
Starting from Ram's answer, and using a more functional approach, you could also try:
This way it should be easy to tweak the code and pass some configuration options to all of your plots (e.g. show/hide ticks, set the same bottom/top limits for all the plots, etc).
In Altair version 3.1 or newer (released June 2019), wrapped facets are supported directly within the Altair API. Modifying your iris example, you can wrap your facets at two columns like this:
Alternatively, the same chart can be specified with the facet as an encoding:
The columns argument can be similarly specified for concatenated charts in
alt.concat()
and repeated chartsalt.Chart.repeat()
.Here's a general solution that has a spot to add layers. The DataFrame in this case has three columns and is in long form.