ggplot annotate brakes axis - r

i want to insert a text into my ggplot chart. The text got a subscript and a supersubscript like X[X} = 1,00*Y R^2 = 0,90. For that i used the funktion paste(expression()) into annotate(label=()).
In the graphics pane the whole plot looks fine, like i needed. But if i want to save the plot into a svg using the svg.save function the plot missing the Axis and the annotate Text.
Without annotate the whole svg is fine. So i guess, the soloution is fixing the paste(expression()) function. But i didnt found a solution for that.
Data <- read.csv2("Data.csv", header = TRUE, sep = ";", dec = ",")
Data$ï..Date <- as.Date(Data$ï..Date, format = "%d.%m.%Y")
Gesamt_Plot1 <- ggplot() +
geom_point(aes(X$EC,Y$BC), show.legend = FALSE, shape = 1, size = 1.5, na.rm = TRUE)+
geom_abline(linetype = "dashed")+
geom_segment(aes(x = 0.19,xend = 5.49, y = G1_slp*0.19, yend = G1_slp*5.49), color = "black", size = 1.2, na.rm = TRUE)+
annotate(geom="text", x = 4, y=6.4, parse = T, label=paste(expression(EBC~"="~"0,92*"*EC[TOR]~~R²~"="~"0,89")), color="black")+
annotate(geom="text", x=0.1, y=7, label="a)", color="black")+
labs(colour = "", x=expression(EC[TOR]~"in"~mu*g~m^-3), y=expression(EBC~"in"~mu*g~m^-3))+
theme_bw()+
theme(axis.text.y=element_text(size = 12), axis.text.x = element_text(size = 12),
axis.title = element_text(size = 12), legend.position = "bottom", panel.grid.minor = element_blank())+
scale_x_continuous(limit = c(0,7),
breaks = c(0, 1, 2, 3, 4, 5, 6, 7)
)+
scale_y_continuous(limit = c(0,7),
breaks = c(0, 1, 2, 3, 4, 5, 6, 7)
)
https://i.stack.imgur.com/9axhZ.png
Using R Version 4.0.5 and ggplot v3.3.3.

Not sure I can reproduce your problem, but I think you should not be using paste(expression(..)), just use expression(..). (Incidentally, I changed from your R² to R^2 in the expression; I'm not certain if it's a UTF problem in my emacs/ess or not. Try it both ways if you prefer.)
ggplot(mtcars, aes(mpg, disp)) +
geom_point() +
annotate(geom="text", x=20, y=60,
label=expression(EBC~"="~"0,92*"*EC[TOR]~~R^2~"="~"0,89"))
# Warning in is.na(x) :
# is.na() applied to non-(list or vector) of type 'expression'
In the R graphics pane, I see
Saving to svg:
ggsave(filename="mt.svg")
# Warning in is.na(x) :
# is.na() applied to non-(list or vector) of type 'expression'
which then shows
Note: due to a long-standing ... bug/feature (?) in ggplot2, it warns about expressions. Granted, it's just a warning (and it plots fine), so it can be ignored. See Why does ggplot annotate throw this warning: In is.na(x) : is.na() applied to non-(list or vector) of type 'expression'. Another method is this:
ggplot(mtcars, aes(mpg, disp)) +
geom_point() +
annotate(geom="text", x=20, y=60,
label=list('EBC~"="~"0,92*"*EC[TOR]~~R^2~"="~"0,89"'),
parse=TRUE) +
labs(colour = "", x=expression(EC[TOR]~"in"~mu*g~m^-3), y=expression(EBC~"in"~mu*g~m^-3)) +
theme_bw()
(using list('...') instead of expression(...), and adding parse=TRUE). This produces the same effect.

Related

How to add geom_text in ggarrange?

I get warning message :
In as_grob.default(plot) : Cannot convert object of class LayerInstanceLayerggprotogg into a grob.
The geom_text I would like to add is geom_text(aes(label = rownames(data)), size = 4).
If I add it in the ggplot function, I get this warning message ,When trying to run the ggarrange :
Error: Aesthetics must be either length 1 or the same as the data (87): label
mgp_df = ggplot2::mpg
mpg_df2 = mgp_df[1:50,]
rownames(mgp_df)<-make.names(mgp_df$manufacturer, unique = TRUE)
p1<-ggplot(mgp_df, aes(x=cty, y=hwy)) +
geom_smooth(method=lm)+
theme_classic()+
geom_text(aes(label = rownames(mgp_df)), size = 4) +
scale_x_continuous(name="testx")+
scale_y_continuous(name="testy", limits=c(35, 90))
p2<-ggplot(mpg_df2, aes(x=cty, y=hwy)) +
geom_smooth(method=lm)+
theme_classic()+
geom_text(aes(label = rownames(mpg_df2)), size = 4) +
scale_x_continuous(name="testx")+
scale_y_continuous(name="testy", limits=c(35, 90))
figure <- ggarrange(p1, p2,
labels = c("test1", " test2"),
ncol = 1, nrow = 2)
figure
Create a column in data for the labels:
data$labs <- rownames(data)
Then change geom_text to:
geom_text(aes(label = labs), size = 4)

Scientific notation in ggplot

Can anybody tell me how can I use scientific notation in my plot axis THIS WAY with ggplot?
I would like to write the exponential part only in the corners, as you can see in the picture (that plot was made with matplotlib).
Best I can come up with is to use the annotate() function and disabling coord clipping to place text outside the panel bounds. You may have to play a bit with the exact spacing and the expressions will throw warnings.
library(ggplot2)
df <- data.frame(
x = 1:10,
y = 10:1
)
ggplot(df, aes(x, y)) +
geom_point() +
annotate("text", -Inf, Inf, label = expression(""%*%10^1),
hjust = 0, vjust = -1) +
annotate("text", Inf, -Inf, label = expression(""%*%10^-3),
hjust = 1, vjust = 2) +
coord_cartesian(clip = "off") +
theme(plot.margin = margin(t = 30, b = 10, l = 10, r = 10))
#> Warning in is.na(x): is.na() applied to non-(list or vector) of type
#> 'expression'
#> Warning in is.na(x): is.na() applied to non-(list or vector) of type
#> 'expression'
Created on 2020-09-11 by the reprex package (v0.3.0)

Error when assembling plots with cowplot::plot_grid

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

adding a border around a grob (R) [duplicate]

I'm using the code below:
# Libs
require(ggplot2); require(gridExtra); require(grid)
# Generate separate charts
chrts_list_scts <- list()
# Data
data("mtcars")
# A
chrts_list_scts$a <- ggplot(mtcars) +
geom_point(size = 2, aes(x = mpg, y = disp,
colour = as.factor(cyl))) +
geom_smooth(aes(x = mpg, y = disp),
method = "auto") +
xlab("MPG") +
ylab("Disp") +
theme_bw() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "none")
# B
chrts_list_scts$b <- ggplot(mtcars) +
geom_point(size = 2, aes(x = mpg, y = drat,
colour = as.factor(cyl))) +
geom_smooth(aes(x = mpg, y = drat),
method = "auto") +
xlab("MPG") +
ylab("Drat") +
theme_bw() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "none")
# C
chrts_list_scts$c <- ggplot(mtcars) +
geom_point(size = 2, aes(x = mpg, y = qsec,
colour = as.factor(cyl))) +
geom_smooth(aes(x = mpg, y = qsec),
method = "auto") +
xlab("MPG") +
ylab("QSEC") +
guides(colour = guide_legend(title = "cyl")) +
theme_bw() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "bottom",
legend.key = element_rect(colour = NA))
# Arrange grid
png(filename = "chrts.PNG", width = 6,
height = 10, units = 'in', res = 300)
title_text <- c("mtcars")
chrts_list_scts$all_scts <- grid.arrange(chrts_list_scts$a,
chrts_list_scts$b,
chrts_list_scts$c,
top =
textGrob(label = title_text,
gp = gpar(
fontsize = 14,
font = 2)))
dev.off()
rm(title_text)
To generate the following chart:
I'm interested in adding border around that chart, as in the picture below:
Attempts
I tried to address this request via adding polygonGrob in the code:
chrts_list_scts$all_scts <- grid.arrange(chrts_list_scts$dep_work,
chrts_list_scts$chld_work,
chrts_list_scts$pens,
polygonGrob(x = c(0,0.5,1.05),
y = c(0,0.5,1.05)
),
top =
textGrob(label = title_text,
gp = gpar(
fontsize = 14,
font = 2)))
but this generates a pointless chart with one line across in the bottom. I had a look at the seeming similar discussion on SO but it wasn't clear to me how to arrive at a working solution.
Side requirements
In addition to generating the border, I would like to:
Be able to exercise some control over the border aesthetics, like changing size and colour of the border.
Ideally, I would like to encapsulate this solution within the arrange.grid call. So at the object chrts_list_scts$all_scts has all elements including charts and neat border around all of them.
I will be happy to accept solutions that address the major requirements with respect to the border only, if there is a suggested solution that matches the remaining two points it will be even nicer.
1) Using the iris example (but further simplified) from the link provided in the question just add the last line. Modify the gpar(...) components (and possibly the width and height) to get different aesthetics. (This is not encapsulated in the grid.arrange call.)
library(ggplot2)
library(grid)
library(gridExtra)
g <- ggplot(iris, aes(Sepal.Width, Sepal.Length)) + geom_point()
grid.arrange(g, g, ncol=2)
# next line adds border
grid.rect(width = .98, height = .98, gp = gpar(lwd = 2, col = "blue", fill = NA))
(continued after plot)
2) This is a variation of solution (1) in which on the plus side encapsulates both the graphics and border in the gt gTree by creating grobs to hold each. On the other hand it does involve some additional complexity:
grid.newpage()
ga <- arrangeGrob(g, g, ncol = 2)
gb <- rectGrob(height = .98, width = .98, gp = gpar(lwd = 2, col = "blue", fill = NA)) # border, no fill
gt <- gTree(children = gList(ga, gb))
grid.draw(gt)
you can add a rectGrob to the gtable
grid.draw(gtable::gtable_add_grob(arrangeGrob(g, g, ncol=2),
rectGrob(gp=gpar(lwd=5, fill=NA)), 1, 1, 1, 2))
NOTE: fill=NA or fill='transparent' is required otherwise the rectangle can mask the objects below it.

How to change font size of plot title when the title is a variable in ggplot2?

I am using ggplot2 to generate a scatter plot. I made the title into a variable, how can I change the font size? The code is as the following:
library("ggplot2")
plotfunc <- function(x){
x +
geom_point() +
geom_smooth(se = FALSE, method = "lm", color = "blue", size = 1) +
opts(title = plottitle,
axis.title.x = theme_text(size = 8, colour = 'black'),
axis.title.y = theme_text(size = 8, colour = 'black', angle = 90))
}
plottitle <- "This is Title"
p <- ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width))
plotfunc(p)
I tried
opts(title = plottitle (size = 10),...
but there was an error:
Error in opts(title = plottitle(size = 10),
axis.title.x = theme_text(size = 8, : could not find function "plottitle"
It was recognized as function which was not what I want.
What should I do? Thanks.
If opts() still works for you then you are using an old version of ggplot2. The newer command is theme(). In any case you don't want to put the actual title label into opts or theme -- use labs()
plotfunc <- function(x) {
x +
geom_point() +
geom_smooth(se = FALSE, method = "lm", color = "blue", size = 1) +
theme_bw() +
theme(axis.title.x = element_text(size = 8, colour = 'black'),
axis.title.y = element_text(size = 8, colour = 'black', angle = 90)) +
labs(title='this', x='that', y='the other')
}
## plottitle <- "This is Title"
p <- ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width))
plotfunc(p)
Ridiculously late answer, but I didn't think the existing answers addressed the actual question:
I made the title into a variable, how can I change the font size?
This works for me and is in the updated ggplot syntax (theme() vs. opts()):
library(ggplot2)
plotfunc <- function(x){
x +
geom_point() +
geom_smooth(se = FALSE, method = "lm", color = "blue", size = 1) +
labs(title = plottitle) +
### pay attention to the ordering of theme_bw() vs. theme()
theme_bw() +
theme(plot.title = element_text(size = 20),
axis.title.x = element_text(size = 12),
axis.title.y = element_text(size = 8))
}
plottitle <- "This is Title"
p <- ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width))
plotfunc(p)
I get the following:
A note about my theme_bw() comment: try running the above, but put theme_bw() last, after the theme(plot.title, ...) bit, as in Stephen Henderson's answer above. You'll note that none of the font sizes take effect. This is because theme_bw() is a preset which will overwrite various custom theme() options if you pass it after they are added.
Just a finnicky thing to watch out for; I've only learned it due to using theme_bw() a lot and banging my head against the wall trying to figure out why other theme() options weren't working before realizing it wasn't my ggplot syntax after all, but the order of my settings. Gotta love coding :)
Also, here's the full list of options you can pass to theme() as a reference for what you can tweak and how.
You put a "(" as the next non-whitespace character after plottitle so the interpreter decided it must be a function. Try
.... opts( title=plottile, size=10)
This was the long list of warming messages:
Warning messages:
1: 'opts' is deprecated.
Use 'theme' instead.
See help("Deprecated")
2: 'theme_text' is deprecated.
Use 'element_text' instead.
See help("Deprecated")
3: 'theme_text' is deprecated.
Use 'element_text' instead.
See help("Deprecated")
4: In opts(title = plottitle, axis.title.x = theme_text(size = 8, colour = "black"), :
Setting the plot title with opts(title="...") is deprecated. Use labs(title="...") or ggtitle("...") instead.

Resources