Reputation: 107
This question is a follow-up to: Annotating text on individual facet in ggplot2
I was trying out the code provided in the accepted answer and got something that was strangely different than the result provided. Granted the post is older and I'm using R 3.5.3 and ggplot2 3.1.0, but what I'm getting doesn't seem to make sense.
library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p <- p + facet_grid(. ~ cyl)
#below is how the original post created a dataframe for the text annotation
#this will produce an extra facet in the plot for reasons I don't know
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")
This is the code from the accepted answer in the linked question. For me it produces the following graph with an extra facet (i.e, an addition categorical variable of 3 seems to have been added to cyl)
#below is an alternative version that produces the correct plot, that is,
#without any extra facets.
ann_text_alternate <- data.frame(mpg = 15,wt = 5,lab = "Text",cyl = 8)
p+geom_text(data = ann_text_alternate,label = "Text")
This gives me the correct graph:
Anybody have any explanations?
Upvotes: 2
Views: 928
Reputation: 76402
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")
Upvotes: 1