%f - fractional seconds (milliseconds)

The new %f pattern formats the millisecond component of a datetime, zero-padded to 3 digits (e.g. 007, 123).

In [1]:
%useLatestDescriptors
%use dataframe
%use lets-plot
kotlin-logging: initializing... active logger factory: Slf4jLoggerFactory
In [2]:
LetsPlot.getInfo()
Out[2]:
Lets-Plot Kotlin API v.4.14.0. Frontend: Notebook with dynamically loaded JS. Lets-Plot JS v.4.10.1.
Outputs: Web (HTML+JS), Kotlin Notebook (Swing), Static SVG (hidden)
In [3]:
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit

val start = LocalDateTime.of(2025, 6, 1, 12, 0, 0)
val t = (0 until 12).map { start.plus(117L * it, ChronoUnit.MILLIS) }
val value = (0 until 12).toList()

val df = dataFrameOf("t" to t, "value" to value)
val data = df.toMap()

On the axis

In [4]:
// Milliseconds only
letsPlot(data) { x = "t"; y = "value" } +
    geomPoint() +
    ggsize(700, 250) +
    scaleXDateTime(format = "%f")
Out[4]:
000 200 400 600 800 000 200 0 2 4 6 8 10 value t
In [5]:
// Seconds + milliseconds
letsPlot(data) { x = "t"; y = "value" } +
    geomPoint() +
    ggsize(700, 250) +
    scaleXDateTime(format = "%S.%f")
Out[5]:
00.000 00.200 00.400 00.600 00.800 01.000 01.200 0 2 4 6 8 10 value t
In [6]:
// Full ISO-like timestamp with milliseconds
letsPlot(data) { x = "t"; y = "value" } +
    geomPoint() +
    ggsize(700, 250) +
    scaleXDateTime(format = "%Y-%m-%dT%H:%M:%S.%f")
Out[6]:
2025-06-01T12:00:00.000 2025-06-01T12:00:00.500 2025-06-01T12:00:01.000 0 2 4 6 8 10 value t

In tooltips

In [7]:
letsPlot(data) { x = "t"; y = "value" } +
    ggsize(700, 250) +
    geomPoint(
        tooltips = layerTooltips()
            .format("^x", "%H:%M:%S.%f")
            .line("t|^x")
            .line("value|^y")
    ) +
    scaleXDateTime(format = "%S.%f")
Out[7]:
00.000 00.200 00.400 00.600 00.800 01.000 01.200 0 2 4 6 8 10 value t