Support limits for Coord in multiple facet plot
I came across this discussion: https://stackoverflow.com/questions/63550588/ggplot2coord-cartesian-on-facets.
Currently, support for different limits in multiple facet plots relies on the Scale, which behaves differently compared to Coord limits. Coord limits, however, are particularly useful for aligning multiple plots.
Would it be possible to add the following function into the ggh4x package? If it is, I’d be happy to make a commit.
coord_facet_limits <- function(xlim_list = NULL, ylim_list = NULL) {
if (!is.list(xlim_list)) xlim_list <- list(xlim_list)
if (!is.list(ylim_list)) ylim_list <- list(ylim_list)
structure(
list(xlim_list = xlim_list, ylim_list = ylim_list),
class = "coord_facet_limits"
)
}
#' @importFrom ggplot2 ggplot_add ggproto ggproto_parent
#' @importFrom vctrs vec_unique_count
#' @export
ggplot_add.coord_facet_limits <- function(object, plot, object_name) {
Parent <- .subset2(plot, "coordinates")
plot$coordinates <- ggproto(
NULL, Parent,
num_of_panels = NULL,
panel_counter = NULL,
setup_layout = function(self, layout, params) {
# we always initialize the panel number and a counter
self$num_of_panels <- vec_unique_count(.subset2(layout, "PANEL"))
self$panel_counter <- 0L
# call the parent method
ggproto_parent(Parent, self)$setup_layout(layout, params)
},
setup_panel_params = function(self, scale_x, scale_y, params = list()) {
current_counter <- self$panel_counter + 1L
on.exit(self$panel_counter <- current_counter)
if (length(.subset2(object, "xlim_list")) >= current_counter) {
xlim <- .subset2(object$xlim_list, current_counter)
} else {
xlim <- NULL
}
if (length(.subset2(object, "ylim_list")) >= current_counter) {
ylim <- .subset2(object$ylim_list, current_counter)
} else {
ylim <- NULL
}
self$limits <- list(x = xlim, y = ylim)
ggproto_parent(Parent, self)$setup_panel_params(
scale_x = scale_x, scale_y = scale_y, params = params
)
}
)
plot
}
Thanks for the suggestion!
I feel like scale_{x/y}_facet() should be up for this task.
Can you give an example of a situation that cannot be resolved by scale_{x/y}_facet() and needs to have this fixed at the level of coords?
Oh it turns out I already gave an example of how to solve the issue you linked to with ggh4x's facet scales: https://stackoverflow.com/a/63569242/11374827.
Thank you for the prompt response. Yes, I have found the answer you posted in the thread.
The main reason I wish to utilize Coord limits is that Scale limits require us to hypothesize the scale type (discrete or continuous), which we cannot always anticipate for the user.
I am currently developing the ggalign package (currently use facetted_pos_scales), which consistently assumes the position scale is continuous. However, this approach is not user-friendly. Therefore, I am exploring the use of Coord limits to align multiple plots in ggalign package.
When aligning the axes of multiple plots, it is crucial to establish the limits for each plot to guarantee accurate alignment of the axes (ensuring that each axis value corresponds). In this context, employing Coord limits is preferable to Scale limits, which can be either discrete or continuous.
Thanks for the clarification! I suppose it is really a limitation in ggplot2 that users have no control over the continuous range of a discrete position scale.
The reason I'm not very keen on adding a coord-limits-per-panel mechanism is because I there already exists the more flexible scale-per-panel mechanism. Yes in this very specific case, coord limits are more convenient, but I don't think people will run into this often enough to justify me taking on maintainership of this mechanism. If you need this mechanism in the ggalign package, isn't it better to implement it in ggalign? That way, you're also protected from me modifying this function to suit my own needs.
Thank you! I'll include this in ggalign pacakge.