ggplot2 scale_x_datetime() in R: Format POSIXct Axis
The scale_x_datetime() function in ggplot2 customizes the X axis when x is a POSIXct datetime. It is the datetime sister of scale_x_date(), supporting time components (hours, minutes).
+ scale_x_datetime(date_breaks = "1 hour", date_labels = "%H:%M")
+ scale_x_datetime(date_labels = "%Y-%m-%d %H:%M")
+ scale_x_datetime(date_breaks = "1 day")
+ scale_x_datetime(timezone = "America/New_York")
+ scale_x_date() # for date-onlyNeed explanation? Read on for examples and pitfalls.
What scale_x_datetime() does in one sentence
scale_x_datetime() formats a POSIXct X axis using strftime codes; supports time components (hours, minutes, seconds) and timezones.
Syntax
scale_x_datetime(date_breaks = NULL, date_labels = NULL, timezone = NULL, ...).
scale_x_datetime; for date-only, scale_x_date. Mixing them produces wrong-looking axes.Five common patterns
1. Hourly axis
2. Daily axis with date labels
3. Combined date + time
4. Specific timezone
5. Limits
date_breaks explicitly to match your data's resolution (1 hour, 15 min, etc.).scale_x_datetime() vs scale_x_date() vs scale_x_time
| Function | x class | Best for |
|---|---|---|
scale_x_datetime() |
POSIXct | Date + time |
scale_x_date() |
Date | Date only |
scale_x_time() |
hms | Time of day, no date |
scale_x_continuous() |
numeric | When x is seconds-since-epoch |
A practical workflow
For server logs or sensor data, datetime axes need tight breaks.
15-minute ticks; UTC display.
Common pitfalls
Pitfall 1: timezone confusion. ggplot uses the data's timezone unless overridden. Set timezone explicitly for displays in a specific zone.
Pitfall 2: x is Date not POSIXct. Use scale_x_date instead. POSIXct adds time component which Date lacks.
scale_x_datetime requires POSIXct x, NOT Date or character. Convert first if needed: mutate(ts = as.POSIXct(ts_str)).Try it yourself
Try it: Plot a simulated 24-hour signal with hourly tick labels. Save to ex_plot.
Click to reveal solution
Explanation: 2-hour ticks with HH:MM labels.
Related ggplot2 / scales functions
After mastering scale_x_datetime, look at:
scale_x_date(): Date-onlyscale_x_time(): hms time-of-dayscale_x_continuous(): numeric xscales::date_breaks(): helper
FAQ
What does scale_x_datetime do in ggplot2?
scale_x_datetime() formats a POSIXct X axis with strftime labels and date-interval breaks. Supports timezones.
What is the difference between scale_x_datetime and scale_x_date?
datetime supports time-of-day (POSIXct). date is for date-only (Date class). Pick by your x's class.
How do I display a specific timezone?
Pass timezone = "America/New_York" (or other Olson name).
How do I format the labels?
Use strftime codes: %H:%M for time, %Y-%m-%d %H:%M for full timestamp.
What if my x is numeric (seconds-since-epoch)?
Convert to POSIXct first: mutate(ts = as.POSIXct(seconds, origin = "1970-01-01")).