Creating multi-panel plots using facets.

Problem

You want to see more aspects of your data and it's not practcal to use the regular aesthetics approach for that.

Solution - facets

You can add one or more new dimentions to your plot using faceting.

This approach allows you to split up your data by one or more variables and plot the subsets of data together.

In this demo we will explore how various faceting functions work, as well as the built-in sorting and formatting options.

To learn more about formatting templates see: Formatting.

In [1]:
%useLatestDescriptors
%use lets-plot
%use krangl
In [2]:
var data = DataFrame.readCSV("https://raw.githubusercontent.com/JetBrains/lets-plot-kotlin/master/docs/examples/data/mpg2.csv")
data.head(3)
Out[2]:
miles per gallonnumber of cylindersengine displacement (cu. inches)engine horsepowervehicle weight (lbs.)time to accelerate (sec.)model yearorigin of carvehicle name
18.08307.0130350412.070USchevrolet chevelle malibu
15.08350.0165369311.570USbuick skylark 320
18.08318.0150343611.070USplymouth satellite

Shape: 3 x 9.

One plot

Create a scatter plot to show how mpg is related to a car's engine horsepower.

Also use the color aesthetic to vizualise the region where a car was designed.

In [3]:
val p = (letsPlot(data.toMap()) {x="engine horsepower"; y="miles per gallon"} + 
         geomPoint {color="origin of car"})
p + ggsize(800, 350)
Out[3]:

More dimentions

There are two functions for faceting:

  • facetGrid()
  • facetWrap()

The former creates 2-D matrix of plot panels and latter creates 1-D strip of plot panels.

We'll be using the number of cylinders variable as 1st fatceting variable, and sometimes the origin of car as a 2nd fatceting variable.

facetGrid()

The data can be split up by one or two variables that vary on the X and/or Y direction.

One facet

Let's split up the data by number of cylinders.

In [4]:
p + facetGrid(x="number of cylinders")
Out[4]:

Two facets

Split up the data by two faceting variables: number of cylinders and origin of car.

In [5]:
p + facetGrid(x="number of cylinders", y="origin of car")
Out[5]:

Formatting and sorting.

Apply a formatting template to the number of cylinders and sort the origin of car values in discending order.

To learn more about formatting templates see: Formatting.

In [6]:
p + facetGrid(x="number of cylinders", y="origin of car", xFormat="{d} cyl", yOrder=-1)
Out[6]:

facetWrap()

The data can be split up by one or more variables. The panels layout is flexible and controlled by ncol, nrow and dir options.

One facet

Split data by the number of cylinders variable and arrange tiles in two rows.

In [7]:
p + facetWrap(facets="number of cylinders", nrow=2)
Out[7]:

Two facets

Split data by origin of car and number of cylinders and arrange tiles in 5 columns.

In [8]:
p + facetWrap(facets=listOf("origin of car", "number of cylinders"), ncol=5)
Out[8]:

Arrange panels vertically.

Use the dir parameter to arrange tiles by columns, in 3 columns (the default tile arrangment is "by row").

Also, format number of cylinders labels and reverse the sorting direction for this facetting variable.

In [9]:
p + facetWrap(facets=listOf("origin of car", "number of cylinders"), 
               ncol=3,
               format=listOf(null, "{} cyl"),
               order=listOf(1, -1),
               dir="v")
Out[9]: