Reputation: 982
I ve read many SO Answers regarding what can cause the error "Discrete value supplied to continuous scale" but I still fail to solve the following issue. In my case, the error is caused by using annotate()
. If get rid of + annotate(...)
everything works well. Else the error is raised.
My code is as follows:
base <- ggplot() +
annotate(geom = "rect", ymin = -Inf , ymax = 0, xmax = 0, xmin = Inf, alpha = .1)
annotated <- base +
geom_boxplot(outlier.shape=NA, data = technicalsHt, aes(x = name, y = px_last))
> base # fine
> annotated
Error: Discrete value supplied to continuous scale
Unfortunately, I cannot give the code leading to the dataframe used here (viz. technicalsHt
) bacause it is very long and reliant on APis. A description of it:
> str(technicalsHt)
'data.frame': 512 obs. of 3 variables:
$ date : Date, format: "2016-11-14" "2016-11-15" ...
$ px_last: num 1.096 0.365 -0.067 0.796 0.281 ...
$ name : Factor w/ 4 levels "Stock Price Strength",..: 1 1 1 1 1 1 1 1 1 1 ...
> head(technicalsHt)
date px_last name
1 2016-11-14 1.09582090 Stock Price Strength
2 2016-11-15 0.36458685 Stock Price Strength
3 2016-11-16 -0.06696111 Stock Price Strength
4 2016-11-17 0.79613481 Stock Price Strength
5 2016-11-18 0.28067475 Stock Price Strength
6 2016-11-21 1.10780834 Stock Price Strength
The code without annotate
works perfectly:
base <- ggplot()
annotated <- annotated +
geom_boxplot(outlier.shape=NA, data = technicalsHt, aes(x = name, y = px_last))
> annotated # fine
I tried playing around with technicalsHt
, e.g. doing the following:
technicalsHt[,3] <- "hi"
technicalsHt[,2] <- rnorm(ncol(technicalsHt), 2,3)
but no matter what, using a annotate
statement raises the error.
EDIT:
following the answer below, I tried to put the data
and aes
in the initial ggplot
call, and have geom_boxplot
from the outset:
base <-
# also tried: base <- ggplot(data = technicalsHt, aes(x = factor(name), y = px_last)) + geom_boxplot(outlier.shape=NA)
annotated <- base + ggplot(data = technicalsHt, aes(x = name, y = px_last)) + geom_boxplot(outlier.shape=NA)
annotate(geom = "rect", ymin = -Inf , ymax = 0, xmax = 0, xmin = Inf, alpha = .1)
this works but it is not really satisfactory since the annotation layer (shading part of the coordinate system) then covers the boxes.
(While e.g., that link also mentions this error in connection with annotate
, the answer given there does not solve my issue, so I would be extremely grateful for help. First of all, which of the variable is causing problem?)
Upvotes: 10
Views: 4054
Reputation: 376
I had this issue and did not find the answer I wanted, so here is my solution. This is a bit prettier than plotting two times the boxplot.
If you want to annotate a rectangle below the points when there is a discrete scale you need to specify that to ggplot
ggplot(mtcars, aes(factor(cyl), mpg)) +
scale_x_discrete() +
annotate(geom = "rect", ymin = -Inf , ymax = 10, xmax = 0, xmin = Inf, alpha = .1) +
geom_boxplot()
Upvotes: 9
Reputation: 63
In response to the layering, the easiest work around that i have found is simply plotting the same box plot twice. I am aware that it is unnecessary code, but it is a very quick fix for the layering issue.
ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_boxplot() +
annotate(geom = "rect", ymin = -Inf , ymax = 10, xmax = 0, xmin = Inf, alpha = .1) +
geom_boxplot()
I cannot notice any image degradation from it as the pixels perfectly overlap. Feel free to correct me if anyone has a UHD monitor.
Upvotes: 2
Reputation: 35187
Switch around the order, and bring the data and main aesthetics into your ggplot
call. You are basically writing this:
p1 <- ggplot() +
annotate(geom = "rect", ymin = -Inf , ymax = 10, xmax = 0, xmin = Inf, alpha = .1)
At this point, p1
has a continuous x axis, since you provided numbers here.
p2 <- p1 + geom_boxplot(aes(factor(cyl), mpg), mtcars)
Now you add another layer that has a discrete axis, this yields an error.
If you write it the 'proper' way, everything is OK:
ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_boxplot() +
annotate(geom = "rect", ymin = -Inf , ymax = 10, xmax = 0, xmin = Inf, alpha = .1)
p.s.: Also it's not that hard to make a reproducible minimal example that accurately shows your problem, as you can see.
Upvotes: 6