Draw lines between two facets in ggplot2 - r

How can I draw several lines between two facets?
I attempted this by plotting points at the min value of the top graph but they are not between the two facets. See picture below.
This is my code so far:
t <- seq(1:1000)
y1 <- rexp(1000)
y2 <- cumsum(y1)
z <- rep(NA, length(t))
z[100:200] <- 1
df <- data.frame(t=t, values=c(y2,y1), type=rep(c("Bytes","Changes"), each=1000))
points <- data.frame(x=c(10:200,300:350), y=min(y2), type=rep("Bytes",242))
vline.data <- data.frame(type = c("Bytes","Bytes","Changes","Changes"), vl=c(1,5,20,5))
g <- ggplot(data=df, aes(x=t, y=values)) +
geom_line(colour=I("black")) +
facet_grid(type ~ ., scales="free") +
scale_y_continuous(trans="log10") +
ylab("Log values") +
theme(axis.text.x = element_text(angle = 90, hjust = 1), panel.margin = unit(0, "lines"))+
geom_point(data=points, aes(x = x, y = y), colour="green")
g

In order to achieve that, you have to set the margins inside the plot to zero. You can do that with expand=c(0,0). The changes I made to your code:
When you use scale_y_continuous, you can define the axis label inside that part and you don't need a seperarate ylab.
Changed colour=I("black") to colour="black" inside geom_line.
Added expand=c(0,0) to scale_x_continuous and scale_y_continuous.
The complete code:
ggplot(data=df, aes(x=t, y=values)) +
geom_line(colour="black") +
geom_point(data=points, aes(x = x, y = y), colour="green") +
facet_grid(type ~ ., scales="free") +
scale_x_continuous("t", expand=c(0,0)) +
scale_y_continuous("Log values", trans="log10", expand=c(0,0)) +
theme(axis.text.x=element_text(angle=90, vjust=0.5), panel.margin=unit(0, "lines"))
which gives:
Adding lines can also be done with geom_segment. Normally the lines (segments) will appear in both facets. If you want them to appear between the two facets, you will have to restrict that in data parameter:
ggplot(data=df, aes(x=t, y=values)) +
geom_line(colour="black") +
geom_segment(data=df[df$type=="Bytes",], aes(x=10, y=0, xend=200, yend=0), colour="green", size=2) +
geom_segment(data=df[df$type=="Bytes",], aes(x=300, y=0, xend=350, yend=0), colour="green", size=1) +
facet_grid(type ~ ., scales="free") +
scale_x_continuous("t", expand=c(0,0)) +
scale_y_continuous("Log values", trans="log10", expand=c(0,0)) +
theme(axis.text.x=element_text(angle=90, vjust=0.5), panel.margin=unit(0, "lines"))
which gives:

Related

Deleting an entire row of facets of unused factor level combination

I want to remove the 2nd row of facets from my plot below because there is no data for that factor combination.
library(ggplot2)
library(grid)
set.seed(5000)
# generate first df
df1 = data.frame(x=rep(rep(seq(2,8,2),4),6),
y=rep(rep(seq(2,8,2),each=4),6),
v1=c(rep("x1",32),rep("x2",64)),
v2=c(rep("y1",64),rep("y2",32)),
v3=rep(rep(c("t1","t2"),each=16),3),
v4=rbinom(96,1,0.5))
# generate second df
df2 = data.frame(x=runif(20)*10, y=runif(20)*10,
v1=sample(c("x1","x2"),20,T))
# plot
ggplot() +
geom_point(data=df1, aes(x=x, y=y, colour = factor(v4)), shape=15, size=5) +
scale_colour_manual(values = c(NA,"black")) + facet_grid(v1+v2~v3, drop = T) +
geom_point(data=df2, aes(x=x,y=y), shape=23 , colour="black", fill="white", size=4) +
coord_equal(ratio=1) + xlim(0, 10) + ylim(0, 10)
I tried to use the idea from this post..
g=ggplotGrob(y)
pos=which(g$layout$t==5 | g$layout$t==6)
g$layout=g$layout[-c(pos),]
g$grobs=g$grobs[-c(pos)]
grid.newpage()
grid.draw(g)
..but got this.
How do I eliminate the white space? Also, is there a straightforward solution to this, without having to manipulate the grobs, etc?
Just modify the data:
df2 <- rbind(cbind(df2, v2 = "y1"),
cbind(df2, v2 = "y2"))
df2 <- df2[!(df2$v1 == "x1" & df2$v2 == "y2"),]
# plot
ggplot() +
geom_point(data=df1, aes(x=x, y=y, colour = factor(v4)), shape=15, size=5) +
scale_colour_manual(values = c(NA,"black")) + facet_grid(v1+v2~v3, drop = T) +
geom_point(data=df2, aes(x=x,y=y), shape=23 , colour="black", fill="white", size=4) +
coord_equal(ratio=1) + xlim(0, 10) + ylim(0, 10)

Why does my plot end up with points that are two different sizes?

I am using ggplot2 to make a boxplot, with individual data points shown on the plot. For some reason, though, I end up with two different point sizes.
I would like to have all my points be size=0.8. What am I doing wrong?
Here is my code:
png(paste("/directory/", hgnc_symbol, "_", curr_gene, ".png", sep=""),
width=4, height=3, pointsize=1, units="in", res=300)
print({
barplot <-
ggplot(curr_data, aes(x = condition, y = tpm, fill=condition)) +
geom_boxplot() +
stat_boxplot(geom ='errorbar') +
geom_jitter(size=0.8) +
guides(fill=FALSE) +
theme_bw() +
labs(title=paste(hgnc_symbol, "_", curr_gene, sep="")) +
labs(x="condition") + labs(y="TPM") +
theme(text = element_text(size=5),
axis.text.x = element_text(angle = 90, hjust = 1, size=6))
})
dev.off()

ggplot does not show legend in geom_histogram

I have this code
ggplot()
+ geom_histogram(aes(x=V1, y=(..count..)/sum(..count..)), fill="red", alpha=.4, colour="red", data=coding, stat = "bin", binwidth = 30)
+ geom_histogram(aes(x=V1,y=(..count..)/sum(..count..)), fill="blue", alpha=.4, colour="blue", data=lncrna, stat = "bin", binwidth = 30)
+ coord_cartesian(xlim = c(0, 2000))
+ xlab("Size (nt)")
+ ylab("Percentage (%)")
+ geom_vline(data=cdf, aes(xintercept=rating.mean, colour=Labels), linetype="dashed", size=1)
that produces a beautiful histogram without legend:
In every post I visit with the same problem, they say to put color inside aes. nevertheless, this does not give any legend.
I tried:
ggplot() + geom_histogram(aes(x=V1, y=(..count..)/sum(..count..),color="red", fill="red"), fill="red", alpha=.4, colour="red", data=coding, stat = "bin", binwidth = 30)
+ geom_histogram(aes(x=V1,y=(..count..)/sum(..count..), color="blue", fill="blue"), fill="blue", alpha=.4, colour="blue", data=lncrna, stat = "bin", binwidth = 30)
+ coord_cartesian(xlim = c(0, 2000))
+ xlab("Size (nt)")
+ ylab("Percentage (%)")
+ geom_vline(data=cdf, aes(xintercept=rating.mean, colour=Labels), linetype="dashed", size=1)
without success.
How can I put a legend in my graph?
If you don't want to put the data in one data.frame, you can do this:
set.seed(42)
coding <- data.frame(V1=rnorm(1000))
lncrna <- data.frame(V1=rlnorm(1000))
library(ggplot2)
ggplot() +
geom_histogram(aes(x=V1, y=(..count..)/sum(..count..), fill="r", colour="r"), alpha=.4, data=coding, stat = "bin") +
geom_histogram(aes(x=V1,y=(..count..)/sum(..count..), fill="b", colour="b"), alpha=.4, data=lncrna, stat = "bin") +
scale_colour_manual(name="group", values=c("r" = "red", "b"="blue"), labels=c("b"="blue values", "r"="red values")) +
scale_fill_manual(name="group", values=c("r" = "red", "b"="blue"), labels=c("b"="blue values", "r"="red values"))
The problem is that you can't map your color into aes because you've got two separete sets of data. An idea is to bind them, then to apply the "melt" function of package reshape2 so you create a dummy categorical variable that you can pass into aes. the code:
require(reshape2)
df=cbind(blue=mtcars$mpg, red=mtcars$mpg*0.8)
df=melt(df, id.vars=1:2)
ggplot()+geom_histogram(aes(y=(..count..)/sum(..count..),x=value, fill=Var2, color=Var2), alpha=.4, data=df, stat = "bin")
There you've got your legend

Hidden labels in ggplot stacked facet

Is there a way to increase ylim of the facets by a certain percentage so my labels fit in nicely?
At the moment the very small bars will have a half cut off label above them. When I use hjust I have the same problem on the top of the large bars.
Here's my code so far:
ggplot(test, aes(x=YEAR, y=(value), fill=variable)) +
labs(title="Test", x=NULL, y="Total", fill=NULL) +
geom_bar(stat="identity"), position="stack") +
facet_grid(variable ~., scales="free") +
theme(legend.position = "none") +
geom_text(aes(x=YEAR, y=(value), label=value), size=3)
You can use expand in scale_y_continuous to add some space at the top and bottom:
e.g.
ggplot(test, aes(x=YEAR, y=(value), fill=variable)) +
labs(title="Test", x=NULL, y="Total", fill=NULL) +
geom_bar(stat="identity"), position="stack") +
facet_grid(variable ~., scales="free") +
theme(legend.position = "none") +
geom_text(aes(x=YEAR, y=(value), label=value), size=3)+
scale_y_continuous( expand = c( 0.05 , 0.05 ) )
This will add a small amount of space at the top and bottom of the y-scale. Make it bigger for more space and 0 to trim axes exactly at the range of the data.
For dscrete scales it works in much the same way:
scale_y_discrete( expand = c( 0.05 , 0.05 ) )
An extreme example (since I don't have access to your data):
mm <- ddply(mtcars, "cyl", summarise, mmpg = mean(mpg))
ggplot(mm, aes(x = factor(cyl), y = mmpg , fill = factor(cyl))) +
geom_bar(stat = "identity") +
geom_text( aes( label=c("RED","GREEN","BLUE" ) ), size = 15 )+
scale_y_continuous( expand = c(0.5,0.5) )

can one offset jitter points in ggplot boxplot

In a ggplot boxplot, it is easy to use jitter to add the raw data points with varying degrees of jitter. With zero jitter the following code
dat <- data.frame(group=c('a', 'b', 'c'), values = runif(90))
ggplot(dat, aes(group, values)) +
geom_boxplot(outlier.size = 0) +
geom_jitter(position=position_jitter(width=0), aes(colour=group), alpha=0.7) +
ylim(0, 1) + stat_summary(fun.y=mean, shape=3, col='red', geom='point') +
opts(legend.position = "right") + ylab("values") + xlab("group")
produces the plot below.
Is it possible to use zero jitter but add an offset such that the points are in a line but shifted left by 25% of the box width? I tried geom_point with dodge but this generated a jitter.
If we convert group to numeric and then add an offset, you seem to get your desired output. There is probably a more effective / efficient way, but give this a whirl:
ggplot(dat, aes(group, values)) +
geom_boxplot(outlier.size = 0) +
geom_point(aes(x = as.numeric(group) + .25, colour=group), alpha=0.7) +
ylim(0, 1) + stat_summary(fun.y=mean, shape=3, col='red', geom='point') +
opts(legend.position = "right") + ylab("values") + xlab("group")

Resources