The error message from my_scale()
gives a jargon-y reason:
Error: Cannot add ggproto objects together. Did you forget to add this object to a ggplot object?
In short, you can only add a scale object (created with scale_...
) to a ggplot
object. The my_scale
function tries to add the two scales, and neither are ggplot
objects, so it fails.
So why does the following code work (I ask rhetorically):
ggplot(data = gdata) +
aes(x = x, y = y, colour = g, shape = g) +
geom_point() +
scale_colour_manual(values=1:10) +
scale_shape_manual(values=1:10)
It's because each step adds to the ggplot
object, so the next component is added to the result of the previous addition. If we could see each combination in sequence...
- The
ggplot
object is created with ggplot(data = gdata)
.
- The aesthetics from
aes(...)
are added to the ggplot
object, and a ggplot
object is returned for the next step.
- The geometry is added, and a
ggplot
object is returned for the next step.
- A color scale is added, and a
ggplot
object is returned for the next step.
- A shape scale is added, and a
ggplot
object returned for R to print.
This happens because the ggplot2
does "operator overloading," where a common operator is given a new ability. You can see it with ggplot2:::"+.gg"
:
function (e1, e2)
{
if (missing(e2)) {
stop("Cannot use `+.gg()` with a single argument. ",
"Did you accidentally put + on a new line?",
call. = FALSE)
}
e2name <- deparse(substitute(e2))
if (is.theme(e1))
add_theme(e1, e2, e2name)
else if (is.ggplot(e1))
add_ggplot(e1, e2, e2name)
else if (is.ggproto(e1)) {
stop("Cannot add ggproto objects together.", " Did you forget to add this object to a ggplot object?",
call. = FALSE)
}
}
<bytecode: 0x000002ccb37ce248>
<environment: namespace:ggplot2>
This is a shallow glimpse into the reasoning, because the ggplot2 package is complex. It has a plethora of classes, operator overloading, its own object system, and tons of non-standard evaluation. And I'm sure I've shown my ignorance at least three times in my explanation above.