Hidden labels in ggplot stacked facet - r

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) )

Related

How do I fill the points of my box plot to be black in ggplot2?

I have a plot that looks like this but I would like the points themselves to be filled black. Is there a way I can do this? Here's my code so far:
plot <- ggplot(data1, aes(x=Group, y=Genome_Size, fill=Group)) + geom_boxplot()
plot + geom_dotplot(binaxis='y', stackdir='center', dotsize=1) + labs(x="Group", y = "Genome size (kb)")+ scale_fill_manual(values = c("Free living" = "cornsilk", "Gut" = "cornsilk3","Pathogen" = "cornsilk4"))
Here I adapt your question to use data we all have, so that we can reproduce your problem and test potential solutions.
It fixed for me by moving fill into an aesthetic specific to the box plot:
ggplot(mtcars, aes(x=gear, y=mpg, fill = gear %>% as.character, group = gear)) +
geom_boxplot() +
geom_dotplot(binaxis='y', stackdir='center', dotsize=1) +
labs(x="Group", y = "Genome size (kb)")+
scale_fill_manual(values = c("3" = "cornsilk", "4" = "cornsilk3", "5" = "cornsilk4"))
Fixed:
ggplot(mtcars, aes(x=gear, y=mpg, group = gear)) +
geom_boxplot(aes(fill = gear %>% as.character)) +
geom_dotplot(binaxis='y', stackdir='center', dotsize=1) +
labs(x="Group", y = "Genome size (kb)")+
scale_fill_manual(values = c("3" = "cornsilk", "4" = "cornsilk3", "5" = "cornsilk4"))
I answered it myself accidentally. Thought I'd leave this up for anyone having the same issue.
geom_dotplot(binaxis='y', stackdir='center', dotsize=1, fill="black")

Controlling the total width of a barplot

How to get rid of all this space where the blue lines are?
Data:
data = data.frame(is_repeat = c(0,0,0,1,1,1,1,1,1,1),
value = c(12000,8000,20000,14000,15000,11000,20000,60000,20000, 20000))
data$is_repeat = factor(data$is_repeat, levels = c(0,1),
labels = c("One-time", "Repeat"))
Plot:
ggplot(data, aes(is_repeat, value)) +
geom_bar(stat = "identity", width = 0.3) +
ggtitle("Title") +
xlab("Type of event") +
ylab("Total Value") +
ylim(0, 150000) +
theme_minimal()
edit: I looked at that question and it did NOT solve my problem. My guess is that in the other question's plot, there are 4 bars, so it looks filled. I want to reduce the total width of the X axis.
another edit: Added data.
If you are looking to remove the space between the bars completely and you don't mind the width of bars you could do it with:
geom_bar(stat="identity", position="stack", width=1)
or theme(aspect.ratio=1)
And to remove the space from the end of the plot to the bars you need
scale_x_discrete(expand = c(0,0), limits=c("One-time", "Repeat"))
So your code looks like this:
ggplot(data, aes(is_repeat, value)) +
geom_bar(stat="identity", position="stack", width=1) +
ggtitle("Title") +
xlab("Type of event") +
ylab("Total Value") +
ylim(0, 150000) +
scale_x_discrete(expand = c(0,0), limits=c("One-time", "Repeat")) +
theme_minimal()
And the output:
You can add space between bars with changing the width=1

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

Draw lines between two facets in ggplot2

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:

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