Specification of First and Last Tick Marks with Scale_X_Date

limits argument in scale_x_date (ggplot) still produces dates outside data.frame range

That's normal, as the argument you look for is not limits but expand, as that's the one adding a little extra space left and right of the limits. You don't have to specify the limits at all, as the minimum and maximum are used by default.

So this code gives you the plot you're after:

ggplot(data=df, aes(x=date, y=value)) +
geom_line() +
scale_x_date(date_breaks = "day", expand = c(0,0)) +
theme(axis.text.x=element_text(angle=90, vjust = 0.5))

From the help page:

expand : A numeric vector of length two giving multiplicative and
additive expansion constants. These constants ensure that the data is
placed some distance away from the axes. The defaults are c(0.05, 0)
for continuous variables, and c(0, 0.6) for discrete variables.

This gives

Sample Image

Using ggplot scale_x_datetime() to set first date on x axis

library(ggplot2)
dat <- data.frame(date = seq(as.Date("2020-03-05 17:00:00",
format = "%Y-%m-%d %H:%M:%S"),
as.Date("2022-03-05 17:00:00",
format = "%Y-%m-%d %H:%M:%S"),
length=18000))
dat$x <- rnorm(18000)
dat$date <- as.POSIXct(dat$date)


ggplot(dat, aes(x=date, y=x)) +
geom_line() +
theme_classic() +
scale_x_datetime(breaks= seq(min(dat$date), max(dat$date), length=6),
date_labels="%b-%y")

Sample Image

Created on 2022-05-03 by the reprex package (v2.0.1)

Breaks for scale_x_date in ggplot2 and R

One approach would be to treat the x-axis as numeric and set the breaks and labels aesthetics with scale_x_continuous().

ggplot(my.data, aes(as.numeric(date), vals)) + 
geom_line(size = 1.5) +
scale_x_continuous(breaks = as.numeric(my.data$date)
, labels = format(my.data$date, format = "%m/%d"))

though the break between 7/24 through 7/28 looks a bit strange in my opinion. However, I think that's what you want? Let me know if I've misinterpreted.

EDIT

As noted above, I wasn't thrilled with the way the breaks looked above, specifically with the gray grid in the background. Here's one way to maintain the rectangular grid and to only label the points where we have data. You could do this all within the ggplot call, but I think it's easier to do the processing outside of ggplot. First, create a vector that contains the sequence of numbers corresponding to the dates. Then we'll update the appropriate labels and replace the NA entries with " " to prevent anything from being plotted on the x-axis for those entries:

xscale <- data.frame(breaks = seq(min(as.numeric(my.data$date)), max(as.numeric(my.data$date)))
, labels = NA)

xscale$labels[xscale$breaks %in% as.numeric(my.data$date)] <- format(my.data$date, format = "%m/%d")
xscale$labels[is.na(xscale$labels)] <- " "

This gives us something that looks like:

  breaks labels
1 15177 07/22
2 15178 07/23
3 15179 07/24
4 15180
5 15181
6 15182
7 15183 07/28
8 15184 07/29

which can then be passed to the scale like this:

scale_x_continuous(breaks = xscale$breaks, labels = xscale$labels)

ggplot: date axis. How to set limits?

Maybe this is what you are looking for. Via the limits you set the range of the data. However, you have to keep in mind that ggplot2 by default expands a continuous axis by 5 percent on each side. The amount of expansion can be set via the expand argument. Additionally, if you want a specific start and/or end age then I would suggest to set the breaks via the breaks arguement instead of using date_breaks:

library(lubridate)
library(ggplot2)
library(tibble)

set.seed(42)
tibble(
date = ymd("2019/12/31") + 1:366,
value = rnorm(1:366)) %>%
ggplot(aes(date, value)) +
geom_line() +
scale_x_date("Day", breaks = seq(ymd("2020/01/01"), ymd("2020/12/31"), by = "10 days"), date_labels = "%b %d",
limits = ymd(c("2020/01/01", "2020/12/31")),
expand = c(0, 0)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Sample Image

R:ggplot and for loop ,scale_x_date overwrites one before

It seems you want to plot 6 year periods of a time-series beneath each other. If you use facet_wrap upon a previously computed factor of timespans the code reduces to a few lines:

library(ggplot2)
library(scales)
library(xts)

set.seed(123)
sunt <- as.xts(rnorm(10958), seq(as.Date("1984-01-01"), as.Date("2014-01-01")-1,by="days"))
names(sunt) <- "Tokyo"

# Divide the time-series into 6 year periods
sunt$period <- cut(x = time(sunt), breaks = "6 years")

ggplot(sunt, aes(x = index(sunt), y = Tokyo)) + xlab("") + ylab("") + geom_line() +
scale_x_date(labels = date_format("%Y/%m/%d")) +
facet_wrap(~period, scales = "free_x", ncol = 1) +
theme(strip.background = element_blank(), strip.text = element_blank())

Sample Image

If you use cut to segment the time-series you benefit from the fact that it accounts for leap years, something that you seem to miss (there are 8 leap years between 1984 and 2014).

How to set date axis limits in ggplot2?

ggplot2 expands the axes. You can prevent the expansion of the x-axis by setting expand = c(0,0) in scale_x_date.

However this can undesirably cut the labels. Maybe a better option is to give the breaks by setting

breaks = seq(as.Date("01/03/2018", '%d/%m/%Y'), as.Date("01/01/2020", '%d/%m/%Y'), by = "month")

in scale_x_date, instead of date_breaks = "1 month".

Annotate first month with year in ggplot2

You can do it with a custom date formatter to remove duplicated years:

my_date_format <- function()
{
function(x)
{
m <- format(x,"%b")
y <- format(x,"%Y")
ifelse(duplicated(y),m,paste(m,y))
}
}

ggplot(DF, aes(x=date, y=y)) +
geom_point() +
scale_x_date(breaks = "1 month", minor_breaks = "1 week", labels=my_date_format())

Custom date plot

Hiding tick marks and tick labels of minimum and maximum limits of axes for base R plots

There are a couple of options. First, you generally want to drop the default axis labels using xaxt='n' or yaxt='n'. Next, you could manually specify the locations of the tick marks in axis() or use the pretty() function with dropping the first and last values (used head and tail in example) to get some nice tick mark locations. It might require some manual fine tuning.

x <- c(1, 2, 3)
xlabs <- c("A", "B", "C")
y <- c(4, 5, 6)

barplot(x,
xlab = "X",
names.arg = xlabs,
ylim = c(0, 3),
ylab = "Y",
yaxt='n' # drops the y axis and tick marks
)
# draw a vertical line that will cover the whole vertical axis, if desired
abline(v=par('usr')[1],lwd=2)
# pretty will give nice tickmark locations, and head and tail drop first and last
# add the 0 to x vector because barplot starts at 0
axis(side=2,tail(pretty(c(0,x)),-1))

plot(x, y,
xlim = c(1, 3),
xlab = "X",
ylim = c(4, 6),
ylab = "Y",
xaxt='n', # no default x axis with ticks
yaxt='n' # no default y axis with ticks
)
# add tickmark and axis locations manually for each axis
# using the pretty function for where the tick marks normally would be, then head and tail to drop first and last
axis(side=1,tail(head(pretty(c(x)),-1),-1))
axis(side=2,tail(head(pretty(c(y)),-1),-1))

scatterplot

barplot



Related Topics



Leave a reply



Submit