Error when assembling plots with cowplot::plot_grid - r

I am using the following code to produce the scatter diagram of a Redundancy Analysis (RDA). The plot is for only one species and I am conducting this analysis for two other species (I am not showing the code for the other two species as it is basically the same).
rda.plot.sap <- ggplot(df1, aes(x=RDA1, y=RDA2)) +
geom_point(aes(shape = df1[,"Enclos"], color = df1[,"Type_enclos"]), size = 2) +
geom_hline(yintercept=0) +
geom_vline(xintercept=0) +
coord_fixed() +
scale_shape_manual(values = c(1, 19)) +
scale_color_manual(values=c('#999999','#E69F00'))
rda.plot.sap <- rda.plot.sap +
geom_segment(data=df2,
aes(x=0, xend=RDA1, y=0, yend=RDA2),
color="red", arrow=arrow(length=unit(0.01,"npc")), size = 0.8) +
geom_text(data=df2,
aes(x=RDA1, y=RDA2, label=rownames(df2),
hjust=0.5*(1-sign(RDA1)) + hjust_sap_x,
vjust=0.5*(1-sign(RDA2) + vjust_sap_x)),
color="red", size=5)
rda.plot.sap <- rda.plot.sap +
geom_segment(data=df3,
aes(x=0, xend=RDA1, y=0, yend=RDA2),
color="blue", arrow=arrow(length=unit(0.01,"npc")), size = 0.8)+
geom_text(data=df3,
aes(x=RDA1, y=RDA2, label=rownames(df3),
hjust=0.5*(1-sign(RDA1)),
vjust=0.5*(1-sign(RDA2))),
color="blue", size=5)
rda.plot.sap <- rda.plot.sap +
theme(panel.background = element_blank(),
axis.title = element_text(size = 20),
axis.line.x = element_line(color="black", size = 1),
axis.line.y = element_line(color="black", size = 1),
axis.text = element_text(size = 15),
legend.title = element_blank(),
legend.text = element_text(size = 15),
legend.key=element_blank(),
legend.position = c(0.15, 0.9)) +
xlim(c(-0.6, 0.4))
rda.plot.sap <- rda.plot.sap +
xlab(paste("RDA1 (", var.rda1, " % - p = ", p.rda1, ")", sep = "")) +
ylab(paste("RDA2 (", var.rda2, " % - p = ", p.rda2, ")", sep = ""))
The code works perfectly fine, and I obtain three separate plots without any error or warnings. The problem is that when I try to assemble these three plots using the function plot_grid of the cowplot package:
final_plot <- plot_grid(rda.plot.sap, rda.plot.epi, rda.plot.het,
nrow = 1, ncol = 3, labels = c("A", "B", "C"))
I always get the same simple error :
"Error: Aesthetics must be either length 1 or the same as the data
(27): shape, colour".
Even stranger, after getting this error, if I want to run again the code of one of the individual plots (of one species only), I get the same error.
This is my first post so I hope I described the problem accurately enough. I am at a loss to understand what is going on here, so thanks in advance to whoever can help.

I'm not sure why, but removing the labels argument from plot_grid() usually fixes this. (You just need to add the labels to each plot individually with geom_text() or ggtitle().)

According to the comment found for this gist, the issue has to do with custom theme not setting the required aesthetics for plot_grid to use for the labels. See the following fix:
final_plot <- plot_grid(rda.plot.sap, rda.plot.epi, rda.plot.het,
nrow = 1, ncol = 3, labels = c("A", "B", "C"),
label_fontfamily = "Times", label_colour = "black")

Related

ggplot how to control fonts on boxplot with stat

How do I control the font-family and size for text elements added to my boxplot:
Following the approach in this question, I have implemented the following code to show the number of observations:
library("ggplot2")
v_min <- -1
v_max <- 3.5
increm <- 0.5
y_limits <- c(v_min, v_max)
increms <- seq(v_min, v_max, increm)
counts <- function(x){
# you can experiment with 'adjust' and 'max-value' to find the perfect position
adjust <- 0.95
return(c(y = adjust * v_max, label = length(x)))
}
ggplot(d1, aes(x = ONRC_Hierarchy, y=lwpMeanRut_inc)) +
geom_boxplot(outlier.alpha = 0.2, outlier.size = 0.5) +
geom_hline(aes(yintercept=0), color="blue", linetype="dotted", size=1)+
stat_summary(fun.data = counts, geom = "text") +
scale_y_continuous(limits = y_limits, breaks = increms) +
xlab("") +
ylab("Rut Increment (mm/year)\n") +
theme_minimal() +
theme(
text = element_text(size = 10, family = "mono"),
axis.text.x=element_text(angle = -35, hjust = 0),
panel.grid.major.y = element_line(color = "lightgray",
size = 0.15,linetype = 2),
panel.grid.minor.y = element_blank(),
panel.grid.major.x = element_blank())
This solution works, as shown in the plot below, except that the font is different from the other graph elements. As you can see, I have tried to control this with the theme() statement, but it does not seem to work. Note, I deliberately used a small mono font to show the difference in the number of observations labels and the other graph elements.
Geom/stat fonts are set in the geom/stat layer, not in theme(). In this case, you can add family = "mono" as an argument to your stat_summary().
The size of fonts in geom_text/geom_label etc. is not on the same scale as element_text theme options, which are in points. You can read more about that here and here.

ggplot legend size when using using breaks

if I use ggplot on this dataframe
library(ggplot2)
date <- as.Date(c("2019-12-18",
"2019-12-19",
"2019-12-20",
"2019-12-23",
"2019-12-24",
"2019-12-26",
"2019-12-27",
"2019-12-30"))
measures <- c( 0.0000000000,
0.0012376239,
-0.0024768434,
0.0024768434,
0.0043196611,
0.0091939970,
-0.0006103144,
-0.0030571104)
theData <- data.frame(date, measures, I=measures<0)
ggplot(theData) + geom_point( aes(x=date, y=measures, col=as.factor(I), size=factor(I))) +
scale_size_discrete(range = c(0.8, 2), guide="none") +
scale_color_manual(values = c("grey80", "steelblue4"), breaks = c("TRUE"), labels = c("negative")) +
labs( col="") +
theme(legend.position = c(0.2, 0.8))
# )
the legend box keeps the space for the FALSE level in the variable I. I tried resizing the legend box with legend.margin, but with no success. If the background of the legend and of the plot are different, it looks quite ugly. Any suggestion?
The reason for the empty gap on the top of the legend was not a space left for the unused factor level "FALSE", but an empty line due to labs( col="").
The correct way to eliminate the legend title is legend.title = element_blank(). Further fine tuning for the label margins can be obtained through legend.margin.
My complete ggplot command is:
ggplot(theData) + geom_point( aes(x=date, y=measures, col=as.factor(I), size=factor(I))) +
scale_size_discrete(range = c(0.8, 2), guide="none") +
scale_color_manual(values = c("grey80", "steelblue4"), breaks = c("TRUE"), labels = c("negative")) +
theme(legend.position = c(0.2, 0.8), legend.title = element_blank(), legend.margin = margin(0, 0.3, 0.2, 0.2, "cm"))

creating custom labels for multilayered plot using ggplot 2 in R

I have this plot
library(dplyr)
library(ggplot2)
indexYear <- as.numeric(2000:2010)
lDLatIndex <- rep.int(4,11)
LDLoneYear <- c(rep.int(3,5), rep.int(2,6))
hba1catIndex <- c(rep.int(8,6), rep.int(7.5,5))
hba1coneYear <- rep.int(7,11)
LDLeffect <- data.frame(indexYear, lDLatIndex, hba1catIndex, hba1coneYear)
LDLeffect %>%
ggplot(., aes(x = indexYear))+
geom_line(aes(y = lDLatIndex, colour=rgb(237/255, 115/255,116/255)), linetype = "solid" , size = 2)+
theme_classic()+
theme(legend.position = "bottom")+
ylab("mean LDL cholesterol (mmol/l) ")+
xlab("Calendar year")+
theme(axis.title = element_text(size = 17, face="bold"), axis.text = element_text(size = 17, face = "bold"))+
scale_x_continuous(breaks = seq(2000,2015, by=1),labels = c(2000,rep("",4),2005,rep("",4), 2010, rep("",4),2015))+
scale_y_continuous(sec.axis = sec_axis(~(.-2.15)*10.929, name = "mean HbA1c (%) "))+
geom_line(aes(y = LDLoneYear, colour=rgb(237/255, 115/255,116/255)), linetype = "dashed" , size = 2)+
geom_line(aes(y = hba1coneYear, colour=rgb(152/255, 201/255,139/255)), linetype = "twodash" , size = 2)+
geom_line(aes(y = hba1catIndex, colour=rgb(152/255, 201/255,139/255)), linetype = "F1" , size = 2)
I know that usually, the best option is to supply data in long format for ggplot, but I couldn't get it to work. The plot above produces a strange legend that I cannot understand how got there.
I see that the names to the legend added are from the colour definitions.
What I want to make is legends that show the colour and linetype and name for each variable plotted, preferably with the option of adding custom names. I looked through a lot of pages with suggestions, but most makes use of long format which I cannot figure out because I wanted different linetypes and colours by two and two. The rest couldn't help me address this strange expression in the labelling.
Would below proposal go into right direction? Main points are: using "melt" from reshape2 for bringing data in ggplot-friendly shape. And with scale_linetype_manual and scale_colour_manual I'm explicitly providing colours and line types.
library(dplyr)
library(ggplot2)
library(reshape2) ## for "melt"
indexYear <- as.numeric(2000:2010)
lDLatIndex <- rep.int(4,11)
LDLoneYear <- c(rep.int(3,5), rep.int(2,6))
hba1catIndex <- c(rep.int(8,6), rep.int(7.5,5))
hba1coneYear <- rep.int(7,11)
LDLeffect <- data.frame(indexYear, lDLatIndex, hba1catIndex, hba1coneYear, LDLoneYear)
melted_df <- melt(LDLeffect, id.vars="indexYear", measure.vars=c("lDLatIndex", "hba1catIndex", "hba1coneYear", "LDLoneYear"))
ggplot(melted_df, aes(x=indexYear, value, colour=variable)) +
geom_line(aes(linetype=variable), size = 2) +
scale_linetype_manual(values=c("F1", "twodash", "solid", "dashed")) +
scale_colour_manual(values=c(rgb(237/255, 115/255,116/255), rgb(237/255, 115/255,116/255), rgb(152/255, 201/255,139/255), rgb(152/255, 201/255,139/255))) +
theme_classic() +
theme(legend.position = "bottom")+
ylab("mean LDL cholesterol (mmol/l)")+
xlab("Calendar year")+
theme(axis.title = element_text(size = 17, face="bold"), axis.text = element_text(size = 17, face = "bold"))+
scale_x_continuous(breaks = seq(2000,2015, by=1),labels = c(2000,rep("",4),2005,rep("",4), 2010, rep("",4),2015))+
scale_y_continuous(sec.axis = sec_axis(~(.-2.15)*10.929, name = "mean HbA1c (%)"))

Changing line color when I have a geom_errorbar with ggplot

I have the following code:
library(ggplot2)
library(gridExtra)
data = data.frame(fit = c(9.8,15.4,17.6,21.6,10.8), lower = c(7.15,12.75,14.95,18.95,8.15), upper = c(12.44,18.04,20.24,24.24,13.44), factors = c(15,20,25,30,35), var = rep("Fator", 5))
gp <- ggplot(data, aes(x=factors, y=fit, ymax=upper, ymin=lower))
gp <- gp + geom_line(aes(group=var),size=1.2) +
geom_errorbar(width=.8, size=1, aes(colour='red')) +
geom_point(size=4, shape=21, fill="grey") +
labs(x = paste("\n",data$var[1],sep=""), y =paste("Values","\n",sep="")) +
theme(legend.position = 'none', axis.text = element_text(size = 11), plot.margin=unit(c(0.4,0.4,0.4,0.4), "cm"), axis.text.x = element_text(angle=45, hjust = 1, vjust = 1)) +
ylim((min(data$lower)), (max(data$upper)))
I want to change the line color after I have the ggplot object. I'm trying:
gp + scale_color_manual(values = "green")
but it change the error bar color and not the line color.
1)What should I do to change the line color?
2)How can I change the points color?
Thanks!
Try this:
gp$layers[[1]] <- NULL
gp + geom_line(aes(group = var),color = "green",size = 1.2)
A similar technique should work for the points layer. Technique was dredged up from my memories of a similar question.
I just looked at the contents of gp$layers manually to see which was which. I presume that the order will be the order in which they appear in your code, but I wouldn't necessarily rely on that.

Rounding % Labels on bar chart in ggplot2

q1 <- qplot(factor(Q1), data=survey, geom="histogram", fill=factor(Q1), ylim=c(0,300))
options(digits=2)
q1 + geom_bar(colour="black") +
stat_bin(aes(label=..count..), vjust=-2, geom="text", position="identity") +
stat_bin(geom="text", aes(label=paste(..count../sum(..count..)*100,"%"), vjust=-0.75)) +
labs(x="Question # 1:\n 0 = Didn't respond, 1 = Not at all familiar, 5 = Very familiar") +
opts(title="Histogram of Question # 1:\nHow familiar are you with the term 'Biobased Products'?",
legend.position = "none",
plot.title = theme_text(size = 16, , vjust = 1, face = "bold"),
axis.title.x =theme_text(size=14), axis.text.x=theme_text(size=12),
axis.title.y=theme_text(size=14, angle=90), axis.text.y=theme_text(size=12))
As you can see I'm getting way more digits than what is needed, I was hoping the options(digits=2) would do it but I guess not. Any ideas?
Actually you are very close to there.
Here is a minimal example:
df <- data.frame(x = factor(sample(5, 99, T)))
ggplot(df, aes(x)) +
stat_bin(aes(label = paste(sprintf("%.02f", ..count../sum(..count..)*100), "%")),
geom="text")
also, format, round, prettyNum, etc, is available.
UPDATED:
Thanks to #Tommy 's comment, here si a more simple form:
ggplot(df, aes(x)) +
stat_bin(aes(label = sprintf("%.02f %%", ..count../sum(..count..)*100)),
geom="text")

Resources