This page is available as an executable or viewable Jupyter Notebook:



In [1]:
%useLatestDescriptors
%use lets-plot
import java.util.Random
In [2]:
val rand = java.util.Random(123)
val n = 200
val data = mapOf<String, Any>(
    "cond" to List(n) { "A" } + List(n) { "B" },
    "rating" to List(n) { rand.nextGaussian() } + List(n) { rand.nextGaussian() * 1.5 + 1.5 },
)
In [3]:
// Basic histogram of "rating"
val p = lets_plot(data) { x = "rating" } + ggsize(500, 250)
p + geom_histogram(binWidth=0.5)
Out[3]:
In [4]:
// Histogram overlaid with kernel density curve
//  - histogram with density instead of count on y-axis
//  - overlay with transparent density plot

p + geom_histogram(binWidth=0.5, color="black", fill="white") { y = "..density.." } +
    geom_density(alpha=0.2, fill=0xFF6666)
Out[4]:
In [5]:
p + geom_histogram(binWidth=.5, color="black", fill="white") +
    geom_vline(xintercept=(data["rating"] as List<Double>).average(), color="red", linetype="dashed", size=1.0)
Out[5]:

Histogram and density plots with multiple groups

In [6]:
val p1 = lets_plot(data) {x = "rating"; fill="cond"} + ggsize(500, 250)

// Default histogram (stacked)
p1 + geom_histogram(binWidth=0.5, alpha=.5)
Out[6]:
In [7]:
// Overlaid histograms
p1 + geom_histogram(binWidth=0.5, alpha=0.5, position=Pos.identity)
Out[7]:
In [8]:
// Interleaved histograms
p1 + geom_histogram(binWidth=0.5, alpha=.5, position=Pos.dodge)
Out[8]:
In [9]:
// Density plot
val p2 = ggplot(data) {x="rating"; color="cond"} + ggsize(500, 250)
p2 + geom_density()
Out[9]:
In [10]:
// Density plot with semi-transparent fill
p2 + geom_density(alpha=.3) {fill="cond"}
Out[10]:
In [11]:
// Find the mean of each group
val means = (data["cond"] as List<String> zip data["rating"] as List<Double>)
        .groupBy(keySelector = { it.first }, valueTransform = { it.second })
        .mapValues { it.value.average() }
val cdat = mapOf(
    "cond" to means.keys,
    "rating" to means.values
)
cdat
Out[11]:
{cond=[A, B], rating=[-0.011843241476365302, 1.5547269440141214]}
In [12]:
// Overlaid histograms with means
p2 + geom_histogram(alpha=.3, position=Pos.identity, size=0.0, bins=10) {fill="cond"} +
     geom_vline(data=cdat, linetype="dashed", size=1.0) {xintercept="rating"; color="cond"}
Out[12]:
In [13]:
// Use frqpoly instead of histogram
p2 + geom_freqpoly(bins=10) {color="cond"} +
     geom_vline(data=cdat, linetype="dashed", size=1.0) {xintercept="rating"; color="cond"}
Out[13]:
In [14]:
// Density plots with means
p2 + geom_density() +
     geom_vline(data=cdat, linetype="dashed", size=1.0) {xintercept="rating"; color="cond"}
Out[14]:

Using facets

In [15]:
ggplot(data) {x="rating"} + 
    geom_histogram(binWidth=.5, color="black", fill="white") +
    facet_grid("cond")
Out[15]:

Box plots

In [16]:
// A basic box plot
val p3 = ggplot(data) {x="cond"; y="rating"} + ggsize(300, 200)
p3 + geom_boxplot()
Out[16]:
In [17]:
// A basic box with the conditions colored
p3 + geom_boxplot {fill="cond"}
Out[17]:
In [18]:
// Style outliers
p3 + geom_boxplot(outlierColor="red", outlierShape=8, outlierSize=5)
Out[18]: