A lollipop plot displays each element of a dataset as a segment and a circle. It is usually combined with the count
stat, and is especially useful when you have several bars of the same height.
%useLatestDescriptors
%use lets-plot
LetsPlot.getInfo()
Lets-Plot Kotlin API v.4.4.0. Frontend: Notebook with dynamically loaded JS. Lets-Plot JS v.3.2.0.
%use dataframe
import jetbrains.datalore.plot.base.stat.regression.LinearRegression
import kotlin.random.Random
val rnd = Random(0)
val data = mapOf(
"x" to (-15..14).toList(),
"y" to (0..29).map { rnd.nextDouble(1.0, 5.0) },
"sugar" to (150..179).toList()
)
letsPlot(data) { x = "x"; y = "y" } + geomLollipop() + ggsize(600, 200)
size
, stroke
and linewidth
¶val plots = listOf(
letsPlot(data) { x = "x"; y = "y"; size = "sugar" } +
geomLollipop() + ggtitle("variable 'size'"),
letsPlot(data) { x = "x"; y = "y"; size = "sugar"; stroke = "sugar" } +
geomLollipop() + ggtitle("variable 'size' and 'stroke'"),
letsPlot(data) { x = "x"; y = "y"; size = "sugar"; linewidth = "sugar" } +
geomLollipop() + ggtitle("variable 'size' and 'linewidth'")
)
gggrid(plots, ncol=1) + ggsize(800, 800)
fatten
¶gggrid(
listOf(
letsPlot(data) { x = "x"; y = "y"} + geomLollipop() + ggtitle("fatten=2.5 (default)"),
letsPlot(data) { x = "x"; y = "y"} + geomLollipop(fatten = 5) + ggtitle("fatten=5"),
)
)
letsPlot(data) { x = "y"; y = "x" } + geomLollipop(dir = "h")
val slope = 0.5
val intercept = 1
val abline = letsPlot(data) { x = "x"; y = "y" } +
geomABLine(intercept = intercept, slope = slope, color = "black", linetype = "dotted", size = 1.5) +
coordFixed(ylim = -12 to 12)
gggrid(
listOf(
abline + geomLollipop(intercept = intercept, slope = slope, shape = 21) + ggtitle("dir='v' (default)"),
abline + geomLollipop(intercept = intercept, slope = slope, shape = 21, dir = "h") + ggtitle("dir='h'"),
abline + geomLollipop(intercept = intercept, slope = slope, shape = 21, dir = "s") + ggtitle("dir='s'"),
)
)
stat
¶val df = DataFrame.readCSV("https://raw.githubusercontent.com/JetBrains/lets-plot-docs/master/data/mpg.csv")
df.head(3)
DataFrame: rowsCount = 3, columnsCount = 12
gggrid(
listOf(
letsPlot(df.toMap()) { x = "class" } + geomLollipop(stat = Stat.count()) + ggtitle("stat='count'"),
letsPlot(df.toMap()) { x = "hwy" } + geomLollipop(stat = Stat.bin()) + ggtitle("stat='bin'"),
letsPlot(df.toMap()) { x = "hwy" } + geomLollipop(stat = Stat.density(n=30)) + ggtitle("stat='density'")
)
)
letsPlot(df.toMap()) { x = "hwy"; y = "cty" } +
geomBin2D(binWidth = 1 to 1) +
ggmarginal("r", size=.2,
layer = geomLollipop(stat = Stat.count(), orientation = "y", size = 1) { color = "..count.." } )
val xs = df["hwy"].toList().map { (it as Number).toDouble() }
val ys = df["cty"].toList().map { (it as Number).toDouble() }
fun linearModel(x: Double) = LinearRegression(xs, ys, 0.95).evalX(x).y
val intercept = linearModel(0.0)
val slope = linearModel(1.0) - intercept
letsPlot(df.toMap()) { x = "hwy"; y = "cty" } +
geomSmooth(level = 0.99) +
geomLollipop(slope = slope, intercept = intercept,
size = 1.2, shape = 21, color = "black", fill = "magenta") +
coordFixed()