Drawing Minor Ticks (Not Grid Ticks) in Ggplot2 in a Date Format Axis

Adding minor tick marks to the x axis in ggplot2 (with no labels)

This would do it in the precise instance:

scale_x_continuous(breaks= seq(1900,2000,by=10), 
labels = c(1900, rep("",4), 1950, rep("",4), 2000),
limits = c(1900,2000), expand = c(0,0)) +

Here's a function that is not bullet-proof but works to insert blank labels when the beginning and ending major labels are aligned with the start and stopping values for the at argument:

insert_minor <- function(major_labs, n_minor) {labs <- 
c( sapply( major_labs, function(x) c(x, rep("", 4) ) ) )
labs[1:(length(labs)-n_minor)]}

Test:

p <- ggplot(df, aes(x=x, y=y))
p + geom_line() +
scale_x_continuous(breaks= seq(1900,2000,by=10),
labels = insert_minor( seq(1900, 2000, by=50), 4 ),
limits = c(1900,2000), expand = c(0,0)) +
scale_y_continuous(breaks = c(20,40,60,80), limits = c(0,100)) +
theme(legend.position="none", panel.background = element_blank(),
axis.line = element_line(color='black'), panel.grid.minor = element_blank())

Don't want to display all labels for minor ticks from ggplot2

You could do this.

ggplot(dfr, aes(x, y)) + 
geom_point() +
scale_x_log10(breaks = breaks, labels = c(breaks[1:3], rep("", 24)))

yields:

Sample Image

Insert ticks for days with labels for weeks

My work-around is to create a helper-data.frame, with breaks and (a lot of empty) labels. This way, you can use the major-breaks (with ticks!), and just label them with "".

df.labels <- df %>% 
mutate( x_date = as.Date(date) ) %>%
#create labels on every Monday, using lubridate::wday, if not
#a Monday, add empty "" label.
mutate( label = ifelse( lubridate::wday( x_date ) == 2,
format( x_date, "%d%b" ),
"" ) )

df %>%
mutate(
x_date = as.Date(date)
) %>%
ggplot(aes(x = x_date, y = cured)) +
geom_point() +
scale_x_date(
breaks = df.labels$x_date,
labels = df.labels$label )

Sample Image

X-axis major and minor tick date labels and breaks (epicurve)

This gets you a bit further (I didn't add the lines), but it's pretty manual work.

In the main plot, I:

  • use a random seed to make it reproducible :-)
  • pre-compute the M/F counts per day
  • rotate the X axis labels (just using day short name)
  • expand the plot margins to accommodate extra X axis annotations

Then I:

  • generate and add the non-rotated, in-month day #'s via annotation_custom
  • generate and add the non-rotated month numbers via annotation_custom
  • build the final plot grid structure
  • turn off the panel clip rect
  • draw the graph with grid.draw

You'll prbly want to play with the spacing a bit.

This should be enough to get you going (and adding the lines should be pretty doable with lineGrob).

library(dplyr)
library(ggplot2)
library(scales)
library(grid)
library(gridExtra)

set.seed(1492) # reproducible

df = data.frame(dates = Sys.Date() + sample(-10:25, 100, replace = T),
sex = sample(c("M", "F"), 25, replace = T))

# pre-compute the M/F counts per date

df.2 <- df %>% group_by(dates, sex) %>% summarise(count=n())

gg <- ggplot(df.2, aes(x=dates, y=count, fill=sex))
gg <- gg + geom_bar(color="black", position="stack", stat="identity")
gg <- gg + scale_x_date(breaks="1 day",
labels=date_format("%a"),
limits = xlmts)
gg <- gg + labs(x=NULL)
gg <- gg + theme_bw()
gg <- gg + theme(axis.text.x=element_text(angle = 90, hjust = 1))
gg <- gg + theme(plot.margin=unit(c(1,1,5,1), "line"))

gg1 <- gg # keep base plot

# make & plot the day #'s

for (d in seq(from=as.Date("2014-09-06"), to=as.Date("2014-11-01"), by="1 day")) {
d1 <- format(as.Date(d, origin="1970-01-01"), "%d")
gg1 <- gg1 + annotation_custom(grob=textGrob(d1, hjust=0, gp=gpar(cex=0.7)), ymin=-0.8, ymax=-0.8,
xmin=as.numeric(d), xmax=as.numeric(d))
}

# add month numbners

gg1 <- gg1 + annotation_custom(grob=textGrob("9", gp=gpar(cex=0.8)), ymin=-1.0, ymax=-1.0,
xmin=as.numeric(as.Date("2014-09-17")), xmax=as.numeric(as.Date("2014-09-17")))
gg1 <- gg1 + annotation_custom(grob=textGrob("10", gp=gpar(cex=0.8)), ymin=-1.0, ymax=-1.0,
xmin=as.numeric(as.Date("2014-10-12")), xmax=as.numeric(as.Date("2014-10-12")))

# build the plot

gg2 <- ggplot_gtable(ggplot_build(gg1))

# no panel clipping
gg2$layout$clip[gg2$layout$name=="panel"] <- "off"

# draw the plot

grid.draw(gg2)

Sample Image

date_minor_breaks in ggplot2

You may have to make major breaks every three months and then pad your labels with blanks to give the illusion of major (labeled) and minor (unlabeled) ticks. See this answer for another example.

First manually make the breaks for the tick marks at every quarter.

breaks_qtr = seq(from = min(z$time), to = max(z$time), by = "3 months")

Then make the year labels and pad these labels with three blanks after each number.

labels_year = format(seq(from = min(z$time), to = max(z$time), by = "1 year"), "%Y")
labs = c(sapply(labels_year, function(x) {
c(x, rep("", 3))
}))

Now use the breaks and the labels with the labels and breaks arguments in scale_x_date. Notice that I'm not using date_labels and date_breaks for this.

ggplot(data = z, aes(x=time,y=type)) +
geom_point() +
scale_x_date(labels = labs, breaks = breaks_qtr, name = "Year") +
theme_tufte() +
theme(legend.position = "none")

Sample Image

Date format for subset of ticks on time axis

You can use your custom formater for labels also using breaks="1 day" argument, you just have to use function(x) after labels= and replace myDate$timestamp with x. This will also solve the third problem.

 + scale_x_date(breaks="1 day", 
labels= function(x) paste(substr(format(x, "%a"),1,1),format(x, "%d"),sep="\n"))

Or you can make your transformation as seperate function and then use it for labels=.

my_date_trans<-function(x) {
paste(substr(format(x, "%a"),1,1),format(x, "%d"),sep="\n")
}

+ scale_x_date(breaks="1 day",labels=my_date_trans)

To change colors for labels you should use theme() and axis.text.x=. Here I using vector of colors that contains 6 time black and then red as your scale starts with Monday. Those colors are then repeated.

ggplot() +
geom_rect(data=rects, aes(xmin=saturdays, xmax=sundays,ymin=-Inf, ymax=Inf), alpha=0.1) +
geom_line(data=myData, aes(x=timestamp, y=value, colour=variable,size=1)) +
geom_point(data=myData, aes(x=timestamp, y=value, colour=variable,size=2)) +
scale_x_date(breaks="1 day",labels=my_date_trans)+
scale_size_continuous(range = c(1.5,5), guide=FALSE)+
theme(axis.text.x=element_text(color=c(rep("black",6),"red")))

Sample Image



Related Topics



Leave a reply



Submit