Reputation: 601
I am making several different plots with different axis ranges, so this question does not apply to only the code I am showing here. I tried modifying the breaks and intervals of tick marks, but for some plots the y-axis always continues after the last break. But for some it just works out fine like this.
Here is my current plot, and the code. I would like to end the y-axis with a tick mark on 60:
# Set nucleotide sequence for x-axis labels
my_labs = c("C", "T", "A", "C", "A", "T", "A", "A", "A", "T", "A", "C", "A", "C", "A", "T", "G", "T", "C", "T", "C", "T", "G", "C", "T", "C", "G", "T", "T", "C", "G", "G", "G", "G", "G", "C", "C", "G", "G", "T", "A", "T", "G", "C", "T", "A", "C", "A", "C", "G", "G", "A", "A", "C", "G", "T", "G", "A", "G", "A", "G", "A", "C", "C", "C", "C", "T", "C", "G", "G", "A", "A", "C", "T", "G", "G", "C", "A", "T", "A", "G", "A", "C", "T", "T", "G", "T", "G", "T", "A", "T", "A", "A", "A", "A", "G", "A", "A", "T")
# Set color of each nucleotide
my_cols = c("Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Blue", "Black", "Black", "Black", "Black", "Black", "Black", "Black", "Black")
ggplot(data = miRNA2) +
geom_line(mapping = aes(x = Position, y = CPM), colour="red") +
scale_y_continuous(breaks = seq(0, 60, 10)) +
ylab("Counts per million") +
scale_x_continuous(breaks=1:99, labels=my_labs, expand = c(0, 0)) +
theme(axis.text.x = element_text(color = my_cols, family = "Courier", size = 6),
panel.grid.minor.x=element_blank(), panel.grid.major.x=element_blank(), panel.grid.minor.y=element_blank(), panel.background = element_blank(),
axis.line = element_line(colour = "black")) +
xlab("Supercontig_1.420:40270-40368") +
ggtitle("Sar-Mir-Nov-2") +
theme(plot.title = element_text(hjust = 0.5))
Upvotes: 4
Views: 7859
Reputation: 8943
This sets the breaks and limits automatically, and it also makes sure that the step for the breaks is some power of 10 multiplied by 1, 2, or 5 (and not 3 or 2.5 like sometimes happens with ggplot's automatic breaks), and it draws the plot lines over the panel boundaries and not vice versa (so if there is a line that has the same value as the end of the y-axis, then half of the line doesn't get cut off):
xy=data.frame(x=0:56,y=sample(-3:68,57,replace=T))
candidates=c(sapply(c(1,2,5),\(x)x*10^c(-20:20)))
xstep=candidates[which.min(abs(candidates-max(xy$x)/7))]
xstart=xstep*floor(min(xy$x)/xstep)
xend=xstep*ceiling(max(xy$x)/xstep)
xbreak=seq(xstart,xend,xstep)
ystep=candidates[which.min(abs(candidates-max(xy$y)/5))]
ystart=ystep*floor(min(xy$y)/ystep)
yend=ystep*ceiling(max(xy$y)/ystep)
ybreak=seq(ystart,yend,ystep)
ggplot(xy,aes(x,y))+
geom_hline(yintercept=c(ystart,yend),color="gray50",linewidth=.3,lineend="square")+
geom_vline(xintercept=c(xstart,xend),color="gray50",linewidth=.3,lineend="square")+
geom_line(linewidth=.4)+
labs(x=NULL,y=NULL)+
coord_cartesian(clip="off")+ # don't clip off lines that fall on plot boundaries
scale_x_continuous(limits=c(xstart,xend),breaks=xbreak,expand=c(0,0))+
scale_y_continuous(limits=c(ystart,yend),breaks=ybreak,expand=c(0,0))+
theme(
axis.text=element_text(size=8,color="black"),
axis.ticks=element_line(linewidth=.3,color="gray50"),
axis.ticks.length=unit(.2,"lines"),
panel.background=element_rect(fill="white"),
panel.grid=element_blank(),
plot.margin=margin(.7,.7,.3,.3,"lines")
)
ggsave("1.png",width=5,height=3)
Upvotes: 1
Reputation: 1127
just add limits = c(0,60)
and expand = c(0,0)
to your scale_y_continuous
:
scale_y_continuous(breaks = seq(0, 60, 10),
limits = c(0,60),
expand = c(0,0))
Upvotes: 8
Reputation: 3369
Did you want to set ylim max so that the last break shown is rounded to the nearest 10's? As well as all breaks to be in increments of 10?
You can obtain the current ylim of the ggplot by grabbing the y-range of your gg object ggplot_build(gg)$layout$panel_ranges[[1]]$y.range
, and take ceiling of your ylim max to the nearest 10's and similarly set your breaks. This way you can set limits and breaks dynamically depending on the plot.
gg <- ggplot(data = miRNA2) +
geom_line(mapping = aes(x = Position, y = CPM), colour="red") +
scale_y_continuous(breaks = seq(0, 60, 10)) +
ylab("Counts per million") +
scale_x_continuous(breaks=1:99, labels=my_labs, expand = c(0, 0)) +
theme(axis.text.x = element_text(color = my_cols, family = "Courier", size = 6),
panel.grid.minor.x=element_blank(), panel.grid.major.x=element_blank(),
panel.grid.minor.y=element_blank(), panel.background = element_blank(),
axis.line = element_line(colour = "black")) +
xlab("Supercontig_1.420:40270-40368") +
ggtitle("Sar-Mir-Nov-2") +
theme(plot.title = element_text(hjust = 0.5))
# grab y-range of current gg object
ggplot_build(gg)$layout$panel_ranges[[1]]$y.range
gg_ylim_max <- ggplot_build(gg)$layout$panel_ranges[[1]]$y.range[2]
# decide if you want to ceiling to nearest 10's or 5's
library(plyr)
round_any(gg_ylim_max, 10, f = ceiling) # ceiling 10's
round_any(gg_ylim_max, 5, f = ceiling) # ceiling 5's
Please try this, I don't have your data so I can't tell if it's working for you.
gg_ylim_max_round <- round_any(gg_ylim_max, 10, f = ceiling)
gg + scale_y_continuous(breaks = seq(0, gg_ylim_max_round, 10), limits = c(c(0, gg_ylim_max_round)))
Edited for redundancy of the limits, the code should be correct now.
Upvotes: 2