Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support limits for Coord in multiple facet plot #168

Open
Yunuuuu opened this issue Oct 4, 2024 · 6 comments
Open

Support limits for Coord in multiple facet plot #168

Yunuuuu opened this issue Oct 4, 2024 · 6 comments

Comments

@Yunuuuu
Copy link

Yunuuuu commented Oct 4, 2024

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
}
@teunbrand
Copy link
Owner

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?

@teunbrand
Copy link
Owner

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.

@Yunuuuu
Copy link
Author

Yunuuuu commented Oct 4, 2024

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.

@Yunuuuu
Copy link
Author

Yunuuuu commented Oct 4, 2024

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.

@teunbrand
Copy link
Owner

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.

@Yunuuuu
Copy link
Author

Yunuuuu commented Oct 4, 2024

Thank you! I'll include this in ggalign pacakge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants