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



In [1]:
%useLatestDescriptors
%use lets-plot

@file:DependsOn("org.apache.commons:commons-math3:3.6.1")
In [2]:
import org.apache.commons.math3.distribution.MultivariateNormalDistribution
In [3]:
val cov0 : Array<DoubleArray> = arrayOf(doubleArrayOf(1.0, -.8),
                                        doubleArrayOf(-.8, 1.0))

val cov1 : Array<DoubleArray> = arrayOf(doubleArrayOf(1.0, .8),
                                        doubleArrayOf(.8, 1.0))

val cov2 : Array<DoubleArray> = arrayOf(doubleArrayOf(10.0, .1),
                                        doubleArrayOf(.1, .1))
In [4]:
val n = 400

val means0 : DoubleArray = doubleArrayOf(-2.0, 0.0)
val means1 : DoubleArray = doubleArrayOf(2.0, 0.0)
val means2 : DoubleArray = doubleArrayOf(0.0, 1.0)

val xy0 = MultivariateNormalDistribution(means0, cov0).sample(n)
val xy1 = MultivariateNormalDistribution(means1, cov1).sample(n)
val xy2 = MultivariateNormalDistribution(means2, cov2).sample(n)
In [5]:
val data = mapOf(
    "x" to (xy0.map { it[0] } + xy1.map { it[0] } + xy2.map { it[0] }).toList(),
    "y" to (xy0.map { it[1] } + xy1.map { it[1] } + xy2.map { it[1] }).toList()
)
In [6]:
val p = letsPlot(data) {x="x"; y="y"} + ggsize(600,300) +
        geomPoint(color="black", alpha=.1)
p
Out[6]:
In [7]:
// Basic density 
p + geomDensity2D(color="red")
Out[7]:
In [8]:
// Set contour color by level
//  - change defailt position and size of colorbar
p + geomDensity2D {color="..level.."} +
    scaleColorGradient(low="dark_green", high="yellow", guide=guideColorbar(barHeight=10, barWidth=300)) +
    theme().legendPosition_bottom()
Out[8]:

Filling contours by level

In [9]:
val p1 = letsPlot(data) {x="x"; y="y"} + ggsize(600,300)

// Filled polygons are not always working well - note missing polygons in the middle. 
p1 + geomPolygon(stat=Stat.density2D()) {fill="..level.."} + coordFixed()
Out[9]: