Having trouble aligning histogram and density plots in ggplot2 with cowplot - r

Only the stripped down density plot appears in the output:
library(ggplot2)
library(cowplot)
raises <- attitude$raises
df <- data.frame(raises)
ph <- ggplot(df, aes(x = raises)) +
geom_histogram(binwidth = 1, color = "black", fill = "light grey") +
scale_x_continuous(breaks = seq(40, 90, by = 10)) +
ylim(0,3) +
theme_classic()
pd <- ggplot(df, aes(x = raises)) +
geom_density() +
scale_x_continuous(breaks = seq(40, 90, by = 10)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.1)), position = "right") +
theme_classic() +
theme(axis.line.x = element_blank(),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank())
alpl <- align_plots(ph, pd, align = "hv", axis = "tblr")
ggdraw(alpl[[1]]) + draw_plot(alpl[[2]])
I would like to overlay them so that you can see the histogram with the frequency as well as the density.

You have an opaque plot background and panel background in your density plot which you need to remove in theme. Obviously, I don't have your data, but the following code gives you the idea:
library(ggplot2)
library(cowplot)
set.seed(1)
df <- data.frame(raises = c(rnorm(100, 65, 10)))
ph <- ggplot(df, aes(x = raises)) +
geom_histogram(binwidth = 1, color = "black", fill = "light grey") +
scale_x_continuous(breaks = seq(40, 90, by = 10), limits = c(40, 90)) +
ylim(0,3) +
theme_classic()
pd <- ggplot(df, aes(x = raises)) +
geom_density() +
scale_x_continuous(breaks = seq(40, 90, by = 10), limits = c(40, 90)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.1)), position = "right") +
theme_classic() +
theme(axis.line.x = element_blank(),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
plot.background = element_blank(),
panel.background = element_blank())
alpl <- align_plots(ph, pd, align = "hv", axis = "tblr")
ggdraw(alpl[[1]]) + draw_plot(alpl[[2]])

Related

Barplot - stacked ggplot percentage barplot starting value NOT 0%

I have a plot like this:
library(ggplot2)
library(reshape2)
library(ggh4x)
data <- data.frame(col1=c("Sample1","Sample2","Sample3","Sample4","Sample5","Sample6"),
col2=c(0.5,0.1,0.4,0.05,0.05,0.9),
col3=c(0.6,0.1,0.3,0.1,0.1,0.8),
col4=c(0.5,0.3,0.2,0.05,0.15,0.8),
col5=c("a","a","a","b","b","b"),
col6=c("c","c","c","c","c","c"))
data2 <- melt(data)
ggplot(data=data2, aes(x = variable, y = value, fill=col1))+
geom_bar(position="stack", stat="identity")+
scale_fill_manual(values=c("#e6194B","#ffe119","#f58231","#911eb4","#42d4f4","#bfef45")) +
scale_y_continuous(expand = c(0, 0),labels = scales::percent) +
facet_nested(~col6 + ~col5, scales = "free_x",space = "free_x",switch = "x") +
ggtitle("Title") +
theme_classic() +
theme(strip.text.y = element_text(angle=0),legend.position = "right",
legend.key.size = unit(0.4, 'cm'),
axis.line = element_line(colour = "black"),
axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),
strip.placement = "outside",
strip.background = element_rect(color = "white", fill = "white"),
axis.title = element_blank()) +
guides(fill=guide_legend(title=NULL, ncol = 1)) +
xlab("X axis") +
ylab("Y axis")
Which creates a barplot like this:
Please take a look
My question is simple, how can I set y-axis starting value to 10% instead of 0% (without changing the code too much). All answers are greatly appreciated! (Similar questions are checked, without success...)
While in general not recommended for bar charts one option to "set" the starting point would be to set the limits via coord_cartesian:
library(ggplot2)
library(ggh4x)
ggplot(data = data2, aes(x = variable, y = value, fill = col1)) +
geom_bar(position = "stack", stat = "identity") +
scale_fill_manual(values = c("#e6194B", "#ffe119", "#f58231", "#911eb4", "#42d4f4", "#bfef45")) +
scale_y_continuous(expand = c(0, 0), labels = scales::percent) +
facet_nested(~ col6 + ~col5, scales = "free_x", space = "free_x", switch = "x") +
ggtitle("Title") +
theme_classic() +
theme(
strip.text.y = element_text(angle = 0), legend.position = "right",
legend.key.size = unit(0.4, "cm"),
axis.line = element_line(colour = "black"),
axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1),
strip.placement = "outside",
strip.background = element_rect(color = "white", fill = "white"),
axis.title = element_blank()
) +
guides(fill = guide_legend(title = NULL, ncol = 1)) +
xlab("X axis") +
ylab("Y axis") +
coord_cartesian(ylim = c(.1, NA))

Label individual plots in facet_grid

I am trying to finish this graph, and what I need is to add the R-squared to each graph individually.
However, the labels are superimposed on each graph.
I used p + geom_text and p + geom_label without positive results.
Trajectories$date<-as.POSIXct(Trajectories$date,"%Y-%m-%d",tz = "UTC")
# Reorder names in a new variable
Trajectories$variable_f = factor(Trajectories$variable,
levels=c("canopy_cover", "Leaf_litter", "Chla", "Shrimps", "macroinvertebrates"))
levels(Trajectories$variable_f) <-
c("textstyle('Canopy openness')",
"textstyle('Leaf litter')",
"textstyle('Chlorophyll-')*italic('a')",
"textstyle('Shrimps')",
"atop(NA,atop(textstyle('Macroinvertebrate'),textstyle('density')))")
# Changes names in Facet_grid ---- es una manera buena, pero no la voy a usar --- Habria que labeller(variable_f = variable_f
#variable_f <- c("Canopy openness", "Leaf litter", "Chlorophyll-a","Shrimps","Macroinvertebrates")
#names(variable_f) <- c("canopy_cover", "Leaf_litter", "Chla", "Shrimps", "macroinvertebrates")
streams <- c("Prieta A", "Prieta B")
names(streams) <- c("QPA", "QPB")
# General graph -----------------------------------------------------------
p<- ggplot(Trajectories, aes(date,value)) +
geom_point(shape = 21, fill = "#bdd7e7", color = "#2171b5", size = 3) +
geom_smooth(se = T, size=1.7, color= "gray20", method = "gam", formula = y ~s(x)) +
geom_hline(yintercept = 0, color="gray20") +
xlab('Year') + ylab("Change in magnitude") +
theme(axis.title.x = element_text(size = 14, angle = 0)) + # axis x
theme(axis.title.y = element_text(size = 14, angle = 90)) + # axis 7
theme(axis.text.x=element_text(angle=0, size=10, vjust=0.5, color="black")) + #subaxis x
theme(axis.text.y=element_text(angle=0, size=10, vjust=0.5, color="black")) + #subaxis y
ylim(-3,3) +
theme(legend.position="none")+
theme(panel.grid.major = element_line(colour = "gray95"), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "black")) +
theme(panel.border = element_rect(colour = "black", fill=NA, size=0.5)) +
facet_grid(vars(stream), vars(variable_f),
labeller = labeller(variable_f = label_parsed, stream = streams)) +
theme(
strip.text.x = element_text(size = 10, color = "black"),
strip.text.y = element_text(size = 10, color = "black"),
strip.placement = "outside") +
theme(strip.background=element_rect(color= "black", fill="gray85")) +
theme(strip.text.x = element_text(margin = margin(0.001,0,0.001,0, "cm"))) +
geom_vline(aes(xintercept=as.POSIXct("2017-09-21")), # Hurricane Maria
col= "red",linetype=4, alpha=0.9) +
geom_vline(aes(xintercept=as.POSIXct("2017-09-6")), # Hurricane Irma
col= "blue",linetype=4, alpha=0.9)
p
I tried to build a data frame with the labels. But it doesn't work, and it overlaps the labels.
labels <- data.frame(variable =c("canopy_cover","Leaf_litter","Chla","Shrimps","macroinvertebrates",
"canopy_cover","Leaf_litter","Chla","Shrimps","macroinvertebrates"),
label=c("R1","R2","R3","R4","R5","R6","R7","R8","R9","R10"),
stream= c("QPA","QPA","QPA","QPA","QPA",
"QPB","QPB","QPB","QPB","QPB"))
labels
p + geom_text(
size = 5,
data = labels,
mapping = aes(x = as.POSIXct("2017-09-6"), y = Inf, label = label),
hjust = 1.05,
vjust = 1.5
)
Thanks in advance

How to separate aesthetics of two different geom_lines?

I'm trying to plot a liine on the x axis which is basically a bunch of zeros and ones. Ones are green and zeros are red. When I try to do that, the color_scale_gradient of the ggplot basically colors on top of the line.
It looks like this
Where the line should be colored as follows:
colorbar is a vector of zeros and ones.
p <- ggplot(data1,aes(newx,newy, group = 1, colour=newy))+
geom_line(size=1.5, show.legend = FALSE)+
scale_colour_gradient(low="red2", high="green3") +
geom_line(data = colorFrame, aes(as.numeric(x)-5,as.numeric(ys), color = colorbar),size=3, show.legend = FALSE)+
xlim(0,1300)
p <- p +
theme(panel.background = element_blank(), axis.ticks.x = element_blank(),
axis.text.x = element_blank(), axis.line.y = element_line(colour = 'black'),
axis.ticks.y.left = element_line(colour = 'black')) +
scale_y_continuous(breaks = seq(0, 12, 1), limits = c(-1, 12), expand = c(0,0))
One solution would be to create two subplots and stitch them together. I use cowplot and theme_void here, but really the second plot below could look however you want it to.
p1 <- ggplot(df, aes(x,y, group = 1, colour=y)) +
geom_line(size=1.5, show.legend = FALSE) +
scale_colour_gradient(low="red2", high="green3") +
theme(panel.background = element_blank(),
axis.ticks.x = element_blank(),
axis.text.x = element_blank(),
axis.line.y = element_line(colour = 'black'),
axis.ticks.y.left = element_line(colour = 'black')) +
scale_y_continuous(breaks = seq(0, 12, 1), limits = c(-1, 12), expand = c(0,0)) +
labs(x = NULL)
p2 <- ggplot(df, aes(x, y = 0, colour=z)) +
geom_line(size=1.5, show.legend = FALSE) +
scale_colour_gradient(low="red2", high="green3") +
theme_void()
cowplot::plot_grid(p1, p2,
ncol = 1,
rel_heights = c(1, .05),
align = 'v')
Data
df <- data.frame(x = 1:50,
y = runif(50, 0, 12),
z = sample(c(0,1), 50, replace = TRUE))

Prevent geom_points and their corresponding labels from overlapping

Thanks for the suggested duplicate, this is however not only about the labels, but is also about adjusting the points themselves so they do not overlap.
have a quick look at the plot below...
I need the coloured points, and their corresponding labels, to never overlap. They should be clustered together and all visible, perhaps with some indication that they are spaced and not 100% accurate, perhaps some sort of call out? Open to suggestions on that.
I've tried adding position = 'jitter' to both geom_point and geom_text, but that doesn't seem to be working (assume it is only for small overlaps?)
Ideas?
# TEST DATA
srvc_data <- data.frame(
Key = 1:20,
X = sample(40:80, 20, replace = T),
Y = sample(30:65, 20, replace = T)
)
srvc_data$Z <- with(srvc_data,abs(X-Y))
t1<-theme(
plot.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank(),
axis.line = element_line(size=.4)
)
main_plot <- ggplot(srvc_data, aes(x = X, y = Y),xlim=c(0,100), ylim=c(0,100)) +
t1 +
theme_bw() +
labs(x="X", y="Y") +
scale_x_continuous(limits = c(0, 100)) +
scale_y_continuous(limits = c(0, 100)) +
geom_abline(intercept = 0, slope = 1, colour="blue", size=34, alpha=.1)+
geom_abline(intercept = 0, slope = 1, colour="black", size=.2, alpha=.5,linetype="dashed")+
geom_point(size = 7, aes(color = Z), alpha=.7) +
scale_color_gradient("Gap %\n",low="green", high="red")+
coord_fixed()+
geom_text(aes(label=Key,size=6),show_guide = FALSE)
main_plot
Produces this plot (of course with your random data it will vary)
Thanks in advance.
Here's your plot with ggrepel geom_text_repel:
library(ggrepel)
# TEST DATA
set.seed(42)
srvc_data <- data.frame(
Key = 1:20,
X = sample(40:80, 20, replace = T),
Y = sample(30:65, 20, replace = T)
)
srvc_data$Z <- with(srvc_data,abs(X-Y))
t1<-theme(
plot.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank(),
axis.line = element_line(size=.4)
)
ggplot(srvc_data, aes(x = X, y = Y),xlim=c(0,100), ylim=c(0,100)) +
t1 +
theme_bw() +
labs(x="X", y="Y") +
scale_x_continuous(limits = c(0, 100)) +
scale_y_continuous(limits = c(0, 100)) +
geom_abline(intercept = 0, slope = 1, colour="blue", size=34, alpha=.1)+
geom_abline(intercept = 0, slope = 1, colour="black", size=.2, alpha=.5,linetype="dashed")+
geom_point(size = 7, aes(color = Z), alpha=.7) +
scale_color_gradient("Gap %\n",low="green", high="red")+
coord_fixed()+
geom_text_repel(aes(label=Key,size=6),show_guide = FALSE)

R stacked bar graph plotting geom_text

I'm trying to plot a stacked bar graph in R using ggplot. I also want to include percentage in each piece of bars for that piece. I tried to follow the posts 1, 2, 3 but the values are not exactly in their respective blocks. My data is a file in dropbox.
My code is as follows:
f<-read.table("Input.txt", sep="\t", header=TRUE)
ggplot(data=f, aes(x=Form, y=Percentage, fill=Position)) +
geom_bar(stat="identity", colour="black") +
geom_text(position="stack", aes(x=Form, y=Percentage, ymax=Percentage, label=Percentage, hjust=0.5)) +
facet_grid(Sample_name ~ Sample_type, scales="free", space="free") +
opts(title = "Input_profile",
axis.text.x = theme_text(angle = 90, hjust = 1, size = 8, colour = "grey50"),
plot.title = theme_text(face="bold", size=11),
axis.title.x = theme_text(face="bold", size=9),
axis.title.y = theme_text(face="bold", size=9, angle=90),
panel.grid.major = theme_blank(),
panel.grid.minor = theme_blank()) +
scale_fill_hue(c=45, l=80)
ggsave("Output.pdf")
The output is-
Any help is greatly appreciated.
Thank you for your help and time!
I think you're using an older version of ggplot2. Because with your code modified for ggplot2 v 0.9.3, I get this:
p <- ggplot(data = df, aes(x = Form, y = Percentage, fill = Position))
p <- p + geom_bar(stat = "identity", colour = "black")
p <- p + geom_text(position = "stack", aes(x = Form, y = Percentage, ymax = Percentage, label = Percentage, hjust = 0.5))
p <- p + facet_grid(Sample_name ~ Sample_type, scales="free", space="free")
p <- p + theme(plot.title = element_text("Input_profile"),
axis.text.x = element_text(angle = 90, hjust = 1, size = 8, colour = "grey50"),
plot.title = element_text(face="bold", size=11),
axis.title.x = element_text(face="bold", size=9),
axis.title.y = element_text(face="bold", size=9, angle=90),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank())
p <- p + scale_fill_hue(c=45, l=80)
p
You see that the text objects are normally placed properly. There are places where the bars are just too short so that the numbers overlap. You can also play with the size parameter.
To rectify that, you could do something like this to add up the numbers by yourself.
df <- ddply(df, .(Form, Sample_type, Sample_name), transform,
cum.perc = Reduce('+', list(Percentage/2,cumsum(c(0,head(Percentage,-1))))))
p <- ggplot(data = df, aes(x = Form, y = Percentage, fill = Position))
p <- p + geom_bar(stat = "identity", colour = "black")
p <- p + geom_text(aes(x = Form, y = cum.perc, ymax = cum.perc, label = Percentage, hjust = 0.5), size=2.7)
p <- p + facet_grid(Sample_name ~ Sample_type, scales="free", space="free")
p <- p + theme(plot.title = element_text("Input_profile"),
axis.text.x = element_text(angle = 90, hjust = 1, size = 8, colour = "grey50"),
plot.title = element_text(face="bold", size=11),
axis.title.x = element_text(face="bold", size=9),
axis.title.y = element_text(face="bold", size=9, angle=90),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank())
p <- p + scale_fill_hue(c=45, l=80)
p
This gives:
Here a solution using barchart from lattice.
library(latticeExtra)
barchart(Percentage~Form|Sample_type*Sample_name,data=dat,
groups =Position,stack=T,
panel=function(...){
panel.barchart(...)
ll <- list(...)
keep <- !is.na(ll$groups[ll$subscripts])
x <- as.numeric(ll$x[keep])
y <- as.numeric(ll$y[keep])
groups <- as.numeric(factor(ll$groups)[ll$subscripts[keep]])
for (i in unique(x)) {
ok <- x == i
ord <- sort.list(groups[ok])
pos <- y[ok][ord] > 0
nok <- sum(pos, na.rm = TRUE)
h <- y[ok][ord][pos]
panel.text(x = rep(i, nok),y = cumsum(h)-0.5*h,
label = h,cex=1.5)
}
},
auto.key = list(columns = 5),
par.settings = ggplot2like(n = 5),
lattice.options = ggplot2like.opts())

Resources