%useLatestDescriptors %use lets-plot @file:DependsOn("org.apache.commons:commons-math3:3.6.1") import org.apache.commons.math3.distribution.MultivariateNormalDistribution val cov0 : Array = arrayOf(doubleArrayOf(1.0, -.8), doubleArrayOf(-.8, 1.0)) val cov1 : Array = arrayOf(doubleArrayOf(1.0, .8), doubleArrayOf(.8, 1.0)) val cov2 : Array = arrayOf(doubleArrayOf(10.0, .1), doubleArrayOf(.1, .1)) 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) 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() ) val p = letsPlot(data) {x="x"; y="y"} + ggsize(600,300) + geomPoint(color="black", alpha=.1) p // Basic density p + geomDensity2D(color="red") // 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().legendPositionBottom() 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() // 'geomDensity2DFilled' is not dependent on poligons order and works a lot better p1 + geomDensity2DFilled {fill="..level.."} p1 + geomBin2D() // Adjust the tile size - make them square and bigger. // Show density instead of count. p1 + geomBin2D(binWidth=1 to 1) {fill="..density.."}