override fun apply()

in plot-base/src/commonMain/kotlin/org/jetbrains/letsPlot/core/plot/base/stat/DensityStat.kt [41:114]


    override fun apply(data: DataFrame, statCtx: StatContext, messageConsumer: (s: String) -> Unit): DataFrame {
        if (!hasRequiredValues(data, Aes.X)) {
            return withEmptyStatValues()
        }

        val xs: List<Double>
        val weights: List<Double>
        if (data.has(TransformVar.WEIGHT)) {
            val filtered = SeriesUtil.filterFinite(
                data.getNumeric(TransformVar.X),
                data.getNumeric(TransformVar.WEIGHT)
            )
            val xsFiltered = filtered[0]
            val weightsFiltered = filtered[1]

            val (xsSorted, weightsSorted) = xsFiltered
                .zip(weightsFiltered).sortedBy { it.first }
                .unzip()
            xs = xsSorted
            weights = weightsSorted

        } else {
            xs = data.getNumeric(TransformVar.X)
                .filterNotNull().filter { it.isFinite() }
                .sorted()
            weights = List(xs.size) { 1.0 }
        }

        if (xs.isEmpty()) return withEmptyStatValues()

        val rangeX = if (trim) {
            val xSummary = FiveNumberSummary(xs)
            DoubleSpan(xSummary.min, xSummary.max)
        } else {
            statCtx.overallXRange() ?: DoubleSpan(-0.5, 0.5)
        }

        val statX = DensityStatUtil.createStepValues(rangeX, n)
        val statDensity = ArrayList<Double>()
        val statCount = ArrayList<Double>()
        val statScaled = ArrayList<Double>()
        val densityFunction = DensityStatUtil.densityFunction(
            xs, weights,
            bandWidth, bandWidthMethod, adjust, kernel, fullScanMax
        )

        val nTotal = weights.sum()
        for (x in statX) {
            val d = densityFunction(x)
            statCount.add(d)
            statDensity.add(d / nTotal)
        }

        val maxm = statCount.maxOrNull()!!
        for (d in statCount) {
            statScaled.add(d / maxm)
        }

        val statQuantile = DensityStatUtil.calculateStatQuantile(statX, statCount, quantiles)

        val statData = DensityStatUtil.expandByGroupEnds(mapOf(
            Stats.X to statX,
            Stats.DENSITY to statDensity,
            Stats.COUNT to statCount,
            Stats.SCALED to statScaled,
            Stats.QUANTILE to statQuantile
        ), Stats.X, Stats.QUANTILE)

        val builder = DataFrame.Builder()
        for ((variable, series) in statData) {
            builder.putNumeric(variable, series)
        }
        return builder.build()
    }