# Understanding when and why Discrete value supplied to continuous scale happens

Hi,
I was trying to include a background annotation in a ggplot but for some reason it throws the discrete value supplied to continous scale error.
if we add a geom blank before annotation it works ( but then the scales limit will depend on whatever data we map to geom blank which is not desired as we want the plot to only show the smooth)
Is there another way to let the annotation start/end from to the plot edges for discrete scales?

``````require(ggplot2)
mtcars\$cylf<- as.factor(mtcars\$cyl)
ggplot(mtcars, aes(x=cylf, y=mpg))+
geom_blank()+
annotate("rect", xmin = -Inf, xmax = Inf,
ymin = 15,ymax = 30,fill="lightblue")+
geom_smooth(aes(group=-1L) )
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
#> Warning in simpleLoess(y, x, w, span, degree = degree, parametric =
#> parametric, : pseudoinverse used at 0.99
#> Warning in simpleLoess(y, x, w, span, degree = degree, parametric =
#> parametric, : neighborhood radius 2.01
#> Warning in simpleLoess(y, x, w, span, degree = degree, parametric =
#> parametric, : reciprocal condition number 2.0055e-016
#> Warning in simpleLoess(y, x, w, span, degree = degree, parametric =
#> parametric, : There are other near singularities as well. 4.0401
#> Warning in predLoess(object\$y, object\$x, newx = if
#> (is.null(newdata)) object\$x else if (is.data.frame(newdata))
#> as.matrix(model.frame(delete.response(terms(object)), : pseudoinverse used
#> at 0.99
#> Warning in predLoess(object\$y, object\$x, newx = if
#> (is.null(newdata)) object\$x else if (is.data.frame(newdata))
#> 2.01
#> Warning in predLoess(object\$y, object\$x, newx = if
#> (is.null(newdata)) object\$x else if (is.data.frame(newdata))
#> as.matrix(model.frame(delete.response(terms(object)), : reciprocal
#> condition number 2.0055e-016
#> Warning in predLoess(object\$y, object\$x, newx = if
#> (is.null(newdata)) object\$x else if (is.data.frame(newdata))
#> as.matrix(model.frame(delete.response(terms(object)), : There are other
#> near singularities as well. 4.0401
`````` ``````ggplot(mtcars, aes(x=cylf, y=mpg))+
annotate("rect", xmin = -Inf, xmax = Inf,
ymin = 15,ymax = 30,fill="lightblue")+
geom_smooth(aes(group=-1L) )
#> Error: Discrete value supplied to continuous scale
`````` Created on 2019-03-13 by the reprex package (v0.2.1)

This is happening because you're converting cylinders to a factor (discrete), but you'll still get warnings from `geom_smooth()` using the default method, because you can't really apply loess to categorical data (which is what factors are/why you encoded cylinder as factors — you can't have part of a cylinder):

``````library(ggplot2)

ggplot(mtcars, aes(x = cyl, y = mpg)) +
geom_blank() +
annotate("rect",
xmin = -Inf, xmax = Inf,
ymin = 15, ymax = 30, fill = "lightblue"
) +
geom_smooth(aes(group = -1L))
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
#> Warning in simpleLoess(y, x, w, span, degree = degree, parametric =
#> parametric, : pseudoinverse used at 3.98
#> Warning in simpleLoess(y, x, w, span, degree = degree, parametric =
#> parametric, : neighborhood radius 4.02
#> Warning in simpleLoess(y, x, w, span, degree = degree, parametric =
#> parametric, : reciprocal condition number 2.0055e-16
#> Warning in simpleLoess(y, x, w, span, degree = degree, parametric =
#> parametric, : There are other near singularities as well. 16.16
#> Warning in predLoess(object\$y, object\$x, newx = if
#> (is.null(newdata)) object\$x else if (is.data.frame(newdata))
#> as.matrix(model.frame(delete.response(terms(object)), : pseudoinverse used
#> at 3.98
#> Warning in predLoess(object\$y, object\$x, newx = if
#> (is.null(newdata)) object\$x else if (is.data.frame(newdata))
#> 4.02
#> Warning in predLoess(object\$y, object\$x, newx = if
#> (is.null(newdata)) object\$x else if (is.data.frame(newdata))
#> as.matrix(model.frame(delete.response(terms(object)), : reciprocal
#> condition number 2.0055e-16
#> Warning in predLoess(object\$y, object\$x, newx = if
#> (is.null(newdata)) object\$x else if (is.data.frame(newdata))
#> as.matrix(model.frame(delete.response(terms(object)), : There are other
#> near singularities as well. 16.16
`````` Created on 2019-03-13 by the reprex package (v0.2.1)

1 Like

This is a simplified reprex example.
In my real plot x axis is categorical by design.
I still need to add a background reference rectangle.
I can try to come us to a closer plot to what I am doing.
E.g. boxplots with a line connecting the medians.

Maybe this example can serve as an easier reference point:

``````library(ggplot2)

ggplot(diamonds, aes(x = cut, y = price)) +
geom_boxplot() +
annotate("rect",
xmin = -Inf, xmax = Inf,
ymin = 15, ymax = 15000, fill = "lightblue",
alpha = .2
)
`````` ``````
class(diamonds\$cut)
#>  "ordered" "factor"
str(diamonds\$cut)
#>  Ord.factor w/ 5 levels "Fair"<"Good"<..: 5 4 2 4 2 3 3 3 1 3 ...
``````

Created on 2019-03-13 by the reprex package (v0.2.1)

Also, do take a look at the Stack Overflow thread I linked, as I think it's closer to the problem you're describing.

Yes my problem is that the annotation "background" layer should come first and not sure how to make ggplot work with that without the geom_blank hack but then the y/x scale would reflect x/y ranges and not just the stat layer that is added afterwards.

Thanks for the discussion, this accidentally solved the problem I just had!!
I also treat the x-axis as factor (for resorting) - but maybe I should try to find another solution.

see how it errors when we do the following and how the factors are reordered when we use the factor levels as xmin and xmax and the annotation does not start from plot edge

``````require(ggplot2)

ggplot(diamonds, aes(x = cut, y = price)) +
annotate("rect",
xmin = -Inf, xmax = Inf,
ymin = 15, ymax = 15000, fill = "lightblue",
alpha = .2
)+
stat_summary(data=diamonds,fun.y="median",geom="line",mapping = aes(group=1L))
#> Error: Discrete value supplied to continuous scale

ggplot(diamonds, aes(x = cut, y = price)) +
annotate("rect",
xmin = "Fair", xmax = "Ideal",
ymin = 15, ymax = 15000, fill = "lightblue",
alpha = .2
)+
stat_summary(data=diamonds,fun.y="median",geom="line",mapping = aes(group=1L))
`````` Created on 2019-03-13 by the reprex package (v0.2.1)

I do. I don't have a solution for you at this point, though. Have you browsed the issues in the GitHub repo to see if there are any open threads related to this? This actually might be somewhat related, but I'm not 100% sure.

If there's nothing else, you can file a new issue.

filed a new issue:

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.