Not an expert, I can't really explain the "why" (though see the end), but I think I have the "how". Let's look at the source code of coord_cartesian()
, which is very simple:
function (xlim = NULL, ylim = NULL, expand = TRUE, default = FALSE,
clip = "on")
{
ggproto(NULL, CoordCartesian, limits = list(x = xlim, y = ylim),
expand = expand, default = default, clip = clip)
}
So, we take create a new ggproto object, that inherits from the existing CoordCartesian
ggroto object, adding a few properties.
Now let's look at the error message:
penguins |>
ggplot() +
geom_point(aes(x = flipper_length_mm, y = body_mass_g)) +
CoordCartesian
#> Error in !expand: invalid argument type
So here the problem is quite specific: it's the lack of the expand
property (that's one one the properties added by coord_cartesian()
). This can also be seen in the traceback()
:
13: default_expansion(scale, expand = expand)
12: view_scales_from_scale(scale_x, self$limits$x, self$expand)
11: setup_panel_params(..., self = self)
...
The problem in step 12 is to call self$expand
that doesn't exist.
So, we can try to correct that:
library(ggplot2)
library(palmerpenguins)
penguins |>
ggplot() +
geom_point(aes(x = flipper_length_mm, y = body_mass_g)) +
CoordCartesian
#> Error in !expand: invalid argument type
CoordCartesian$expand <- TRUE
penguins |>
ggplot() +
geom_point(aes(x = flipper_length_mm, y = body_mass_g)) +
CoordCartesian
#> Warning: Removed 2 rows containing missing values (`geom_point()`).
Created on 2024-01-18 with reprex v2.0.2
One important note, and potentially the explanation of the "why": if you try to copy CoordCartesian
and modify the copy, that modifies the original too!
library(ggplot2)
CoordCartesian$expand
#> NULL
coord_proto <- CoordCartesian
coord_proto$expand <- TRUE
CoordCartesian$expand
#> [1] TRUE
So I guess ggproto objects are mutable and copied by reference; if you use CoordCartesian
directly in your ggplot you risk inadvertently modifying it (and thus affecting every subsequent plot). coord_cartesian()
simply makes a temporary copy that is safe to modify.
The part I don't really know about is why specifically the properties limits
, expand
, default
and clip
are the ones that need to be set during the copy.