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:
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 )
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)
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")
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")))
Related Topics
Does Calculating Correlation Between Two Dataframes Require a Loop
Placement of Error Bars in Barplot Using Ggplot2
List Elements to Dataframes in R
R: How to Match/Join 2 Matrices of Different Dimensions (Nrow/Ncol)
Changing Line Color in Ggplot Based on Slope
How to Create a Single Dummy Variable with Conditions in Multiple Columns
Replace Column Values with Column Name Using Dplyr's Transmute_All
Caret Error: "All the Accuracy Metric Values Are Missing"
Selecting Max Column Values in R
Obtaining Twitter Screen Names from a Twitter List
Standard Eval with Ggplot2 Without 'Aes_String()'
Shiny Leaflet Easyprint Plugin
Calculate Difference Between Dates by Group in R
Reconstruct a Categorical Variable from Dummies in R
Looping Over Combinations of Regression Model Terms
How to Change Gender Factor into an Numerical Coding in R