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.