Axis Minor Ticks¶
The axisMinorTicks and axisMinorTicksLength parameters in theme() control
the appearance of axis minor ticks, i.e., the tick marks drawn between major ticks.
axisMinorTicks- tick line attributes set viaelementLine()axisMinorTicksLength- tick length in pixelsaxisMinorTicksX/axisMinorTicksY,axisMinorTicksLengthX/axisMinorTicksLengthY- directional overrides allow controlling only horizontal or vertical axes.
Minor ticks are placed at positions computed by the scale (e.g., midpoints between major breaks for continuous scales). They do not carry labels as for now.
In [1]:
%useLatestDescriptors
%use lets-plot
In [2]:
LetsPlot.getInfo()
Out[2]:
Lets-Plot Kotlin API v.4.12.2-SNAPSHOT. Frontend: Notebook with dynamically loaded JS. Lets-Plot JS v.4.9.0. Outputs: Web (HTML+JS), Kotlin Notebook (Swing), Static SVG (hidden)
General Usage¶
Minor ticks can improve readability of continuous axes, especially when major breaks are sparse.
In [3]:
val rand = java.util.Random(42)
val x = List(2000) { rand.nextGaussian() }
val dfHist = mapOf("x" to x)
val plotNorm = letsPlot(dfHist) +
geomHistogram(bins = 40, color = "white", fill = "light_sky_blue", alpha = 0.7) { x = "x"; y = "..density.." } +
geomDensity(color = "tomato", size = 1.2, alpha = 0.0) { x = "x" } +
scaleXContinuous(breaks = listOf(-3, -2, -1, 0, 1, 2, 3)) +
labs(title = "Normal Distribution", x = "Value", y = "Count / Density")
plotNorm
Out[3]:
In [4]:
plotNorm +
ggtitle("Normal Distribution with Minor Ticks") +
theme(
axisTicksLength = 8,
axisMinorTicks = elementLine(color = "gray85"),
axisMinorTicksLength = 5,
axisMinorTicksX = elementLine(color = "gray66", size = 2),
)
Out[4]:
Minor Ticks as Separators¶
Minor ticks can be styled as vertical separators, helping distinguish categories more clearly.
In [5]:
val csvUrl = "https://raw.githubusercontent.com/JetBrains/lets-plot-docs/master/data/midwest.csv"
val lines = java.net.URL(csvUrl).readText().lines()
val header = lines.first().split(",")
val stateIdx = header.indexOfFirst { it.trim('"') == "state" }
val poptotalIdx = header.indexOfFirst { it.trim('"') == "poptotal" }
val stateNames = mapOf("IL" to "Illinois", "IN" to "Indiana", "MI" to "Michigan", "OH" to "Ohio", "WI" to "Wisconsin")
val stateCol = mutableListOf<String>()
val poptotalCol = mutableListOf<Int>()
for (line in lines.drop(1)) {
if (line.isBlank()) continue
val parts = line.split(",")
val state = parts.getOrNull(stateIdx)?.trim('"') ?: continue
val fullName = stateNames[state] ?: continue
val pop = parts.getOrNull(poptotalIdx)?.trim('"')?.toIntOrNull() ?: continue
stateCol.add(fullName)
poptotalCol.add(pop)
}
val df = mapOf("state" to stateCol, "poptotal" to poptotalCol)
println("Rows: ${stateCol.size}")
Rows: 437
In [6]:
val basePlot = letsPlot(df) +
geomJitter(alpha = 0.3, seed = 42) { x = "state"; y = "poptotal" } +
ggtitle("Population Distribution by State") +
themeGrey()
basePlot
Out[6]:
In [7]:
basePlot +
ggtitle("Minor ticks as separators") +
theme(
// disable major ticks
axisTicksX = elementBlank(),
// and add enlarged minor ticks
axisMinorTicksLengthX = 15.0,
axisMinorTicksX = elementLine(color = "grey")
)
Out[7]: