Annotating Text on Individual Facet in Ggplot2

Annotating text on individual facet in ggplot2

Typically you'd do something like this:

ann_text <- data.frame(mpg = 15,wt = 5,lab = "Text",
cyl = factor(8,levels = c("4","6","8")))
p + geom_text(data = ann_text,label = "Text")

It should work without specifying the factor variable completely, but will probably throw some warnings:

Sample Image

How to annotate text on individual facet in ggplot2

What is going on is a factors issue.

First, you facet by cyl, a column in dataset mtcars. This is an object of class "numeric" taking 3 different values.

unique(mtcars$cyl)
#[1] 6 4 8

Then, you create a new dataset, the dataframe ann_text. But you define cyl as an object of class "factor". And what is in this column can be seen with str.

str(ann_text)
#'data.frame': 1 obs. of 4 variables:
# $ mpg: num 15
# $ wt : num 5
# $ lab: Factor w/ 1 level "Text": 1
# $ cyl: Factor w/ 3 levels "4","6","8": 3

R codes factors as integers starting at 1, level "8" is the level number 3.

So when you combine both datasets, there are 4 values for cyl, the original numbers 4, 6 and 8 plus the new number, 3. Hence the extra facet.

This is also the reason why the solution works, in dataframe ann_text_alternate column cyl is a numeric variable taking one of the already existing values.

Another way of making it work would be to coerce cyl to factor when faceting. Note that

levels(factor(mtcars$cyl))
#[1] "4" "6" "8"

And the new dataframe ann_text no longer has a 4th level. Start plotting the graph as in the question

p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ factor(cyl))

and add the text.

p + geom_text(data = ann_text, label = "Text")

How to annotate text on individual facets in interaction plot (`ggplot2`; `interactions`)?

The issue is that geom_text inherits the global aesthetics from interact_plot. To prevent this simply add inherit.aes = FALSE. Nonetheless you have to add the facetting variable to the labelling df. To prevent that ggplot2 adds a glyph for the text in the legend simply add show.legend = FALSE.

# Create the model
mod1 <- lm(wt ~ am * drat * vs, data = mtcars)

# Make the plot
require(interactions)
#> Loading required package: interactions
p <- interact_plot(mod1,pred="am",modx="drat", mod2="vs")

# Have a look at the dataframe
p$data
#> # A tibble: 600 x 6
#> wt drat vs am modx_group mod2_group
#> <dbl> <dbl> <dbl> <dbl> <fct> <fct>
#> 1 4.13 3.06 0 0 - 1 SD vs = 0
#> 2 4.12 3.06 0 0.0101 - 1 SD vs = 0
#> 3 4.12 3.06 0 0.0202 - 1 SD vs = 0
#> 4 4.11 3.06 0 0.0303 - 1 SD vs = 0
#> 5 4.11 3.06 0 0.0404 - 1 SD vs = 0
#> 6 4.10 3.06 0 0.0505 - 1 SD vs = 0
#> 7 4.10 3.06 0 0.0606 - 1 SD vs = 0
#> 8 4.09 3.06 0 0.0707 - 1 SD vs = 0
#> 9 4.09 3.06 0 0.0808 - 1 SD vs = 0
#> 10 4.08 3.06 0 0.0909 - 1 SD vs = 0
#> # ... with 590 more rows

(dat_text <- data.frame(
text = c("p-value 1", "p-value 2"),
mod2_group = c("vs = 0", "vs = 1")))
#> text mod2_group
#> 1 p-value 1 vs = 0
#> 2 p-value 2 vs = 1


# Add annotations to dataframe
require(ggplot2)
#> Loading required package: ggplot2
p + geom_text(
data = dat_text,
mapping = aes(x = .5, y = 2, label = text), inherit.aes = FALSE, show.legend = FALSE,
hjust = -0.1,
vjust = -1
)

Sample Image

Created on 2020-06-09 by the reprex package (v0.3.0)

Annotation text on individual facet in ggplot2 # 2

@ulrike how about we treat gear and cyl as factors in the facet_grid() call? This way you'll not have to change the data at all. The reason I'm treating gear and cyl as factors because, if you look at the structure of mtcars dataset, you will notice gear and cyl contain discrete values. This means we can coerce them to factor.

library(ggplot2)
ann_text <- data.frame(mpg = 15,wt = 5,lab = "Text",
cyl = factor(8,levels = c("4","6","8")),
gear = factor(4, levels = c("3", "4", "5")))
ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
facet_grid(factor(gear) ~ factor(cyl))+
geom_text(aes(mpg,wt, label=lab),
data = ann_text)

Sample Image

Add text annotations at consistent locations in facet_grid when scale = 'free_y' + ggplot2 + r

Here is how you can control the annotations:

p + geom_text(
size = 5,
data = dat_text,
mapping = aes(x = Inf, y = Inf, label = label),
hjust = 1.05,
vjust = 1.5
)

dat_text <- data.frame(
label = c(-0.2, 0.5, -0.4),
name = c('Jim', 'Bob', 'Sue')
)

Sample Image

Annotating text on individual facets in ggplot2 #2

The easiest way is to tell geom_text to not use Condition for the fill, by setting it to NULL. This way, you can keep fill in the ggplot call and have it applied to all other geoms, without the need to specify it each time.

Create data (since you didn't supply any)

cfit_2 <- data.frame(
Time = c('Pretest', 'Posttest'),
Condition = rep(c('Active control group', 'Training group'), each = 2),
Version = rep(c('Total CFIT', 'CFIT version 1', 'CFIT version 2'), each = 40),
CFIT = rnorm(120, 10, 3)
)

Use your plotting code

p<-ggplot(cfit_2,aes(Time,CFIT,fill=Condition))+
#scale_y_continuous(breaks=1:20)+
scale_fill_manual(values=c("white","lightgrey"))+
geom_violin()+
theme_classic()+
#coord_cartesian(ylim=c(1, 20),xlim=c(1, 2))+
theme(axis.line=element_blank())+
facet_grid(.~Version)+ylab("CFIT raw score")+

geom_segment(x=.3925,xend=.3925,y=1,yend=20)+
geom_segment(x=1,xend=2,y=.015,yend=.015)+

stat_summary(fun.y=mean,geom="point",position=position_dodge(w=.9))+
stat_summary(fun.data=mean_cl_boot,geom="errorbar",position=position_dodge(w=.9),width=0)

(Note that I commented out two lines about the axes, since they were giving me troubles. I also removed the annotated lines, since you didn't supply data for those.)

Add the text

First create the coordinates where you want the asterisks and "NS"es.

ann_text<-read.table(text="
Time CFIT lab Version
Pretest 15 NS 'Total CFIT'
Posttest 7 * 'Total CFIT'
Pretest 3 NS 'CFIT version 1'
Posttest 2 * 'CFIT version 1'
Pretest 2 NS 'CFIT version 2'
Posttest 3 * 'CFIT version 2'
",header=T)

Then annotate.

p + geom_text(data = ann_text, aes(label = lab, fill = NULL))

Result

R Sample Image 1

Of course, the text doesn't look that nice (it's at the wrong y level), but that is because my data is different.



Related Topics



Leave a reply



Submit