ggmagnify

repository·master·Indexed 43 days ago

https://github.com/hughjonesd/ggmagnify

An R package that extends ggplot2 to create magnified insets of specific regions within a plot. It supports various shapes including rectangles, ellipses, and arbitrary outlines, and provides features such as drop shadows, projection lines, and the ability to magnify points based on data mapping using aes().

Tokens
2.6K
Snippets
11
Records
12
Agent score
6%

What's inside ggmagnify

  1. Customize inset shape and appearance

    master

    You can modify the visual style of the magnified inset using several arguments in geom_magnify():

    • Shadows: Set shadow = TRUE to add a drop shadow. This requires the ggfx package. You can customize shadow properties via shadow.args = list(colour = "...", sigma = ..., x_offset = ..., y_offset = ...).
    • Rounded Corners: Use corners = <numeric> to provide a proportional radius for rounded corners.
    • Ellipse Shape: Set shape = "ellipse" to create an elliptical inset (requires R 4.1+ and an appropriate graphics device).
    • Outline Shape: Set shape = "outline" to magnify the convex hull of a set of points (useful for arbitrary regions or maps). Use expand = <numeric> to adjust the expansion of the outline.
    • Custom Shapes: Pass a grid grob object or a data.frame of coordinates to the from argument to magnify an arbitrary shape.
    # Ellipse example
    ggp + geom_magnify(from = from, to = to, shape = "ellipse", shadow = TRUE)
    
    # Rounded corners with shadow
    ggp + geom_magnify(from = from, to = to, corners = 0.1, shadow = TRUE)
    
    # Arbitrary shape from a data frame
    s <- seq(0, 2*pi, length = 7)
    hex <- data.frame(x = 3 + sin(s)/2, y = 6 + cos(s)/2) 
    
    ggpi + geom_magnify(from = hex, to = c(4, 6, 5, 7), shadow = TRUE, aspect = "fixed")
  2. Control layer order for geom_magnify() insets

    master

    geom_magnify() stores the plot state when it is added. Consequently, the order in which you add layers to your ggplot object determines whether those layers appear in the main plot or inside the magnified inset.

    • To include a layer (like geom_smooth()) inside the inset: Add the layer before geom_magnify().
    • To include a layer only in the main plot: Add the layer after geom_magnify().
    # Layer inside the inset:
    ggpi + geom_smooth() + geom_magnify(from = from3, to = to3)
    
    # Layer only in the main plot:
    ggpi + geom_magnify(from = from3, to = to3) + geom_smooth()
  3. Synchronize grid lines between main plot and inset

    master

    By default, the inset may use different grid line breaks than the main plot. To ensure the inset uses the same grid lines as the main graph, explicitly set the breaks in scale_x_continuous() and scale_y_continuous() for both the main plot and the magnification parameters.

    # Fix the grid lines by defining explicit breaks
    ggp2 +
      scale_x_continuous(breaks = seq(2, 5, 0.5)) + 
      scale_y_continuous(breaks = seq(5, 8, 0.5)) + 
      geom_magnify(from = c(2.45, 3.05, 5.9, 6.6), to = c(3.4, 4.4, 5.5, 6.6), shadow = TRUE)
  4. Draw an inset outside the plot region

    master

    To position a magnified inset outside the standard plot boundaries, you must disable clipping in the coordinate system and adjust the plot margins using theme(plot.margin = ...).

    # Use coord_cartesian(clip = "off") to allow drawing outside boundaries
    ggp + 
      coord_cartesian(clip = "off") + 
      theme(plot.margin = ggplot2::margin(10, 60, 10, 10)) + 
      geom_magnify(from = from, to = to + c(0.5e8, 0.5e8, 0, 0), shadow = TRUE)
  5. Magnify multiple regions or create nested insets

    master

    You can call geom_magnify() multiple times on the same plot to create multiple insets. To create an 'inset within an inset', pass a ggplot object that already contains a geom_magnify() layer into the plot argument of a second geom_magnify() call.

    # Multiple insets
    ggm_unif + 
      geom_magnify(from = c(0.05, 0.15, 0.05, 0.15), to = c(0.2, 0.4, 0.2, 0.4)) +
      geom_magnify(from = c(0.25, 0.35, 0.25, 0.35), to = c(0.45, 0.85, 0.45, 0.85))
    
    # Nested inset (inset within an inset)
    ggp + 
      geom_magnify(plot = ggpm, 
                   from = c(-0.3, 0.3, -0.3, 0.3),
                   to = c(-3, -1, -3, -1),
                   expand = FALSE, colour = "white")
  6. Install ggmagnify

    master

    You can install the latest stable release from r-universe or the development version from GitHub.

    From r-universe (Recommended):

    install.packages("ggmagnify", repos = c("https://hughjonesd.r-universe.dev", 
                     "https://cloud.r-project.org"))

    From GitHub (Development version):

    # install.packages("remotes")
    remotes::install_github("hughjonesd/ggmagnify")
    install.packages("ggmagnify", repos = c("https://hughjonesd.r-universe.dev", 
                     "https://cloud.r-project.org"))
  7. Configure graphics devices for geom_magnify()

    master

    Because geom_magnify() uses masks, it requires R version 4.1.0 or higher and a graphics device that supports masking.

    If you are using knitr, the ragg_png device is recommended. If your device does not support masks, you must use shape = "rect", though note that the plot inset will not be clipped to the panel area in this mode.

  8. Magnify points based on data mapping

    master

    Instead of providing static coordinates, you can use aes() to select points to magnify based on logical conditions in your data.

    # Magnify points where Species is 'setosa' and Sepal.Length < 5
    ggpi + geom_magnify(aes(from = Species == "setosa" & Sepal.Length < 5), 
                        to = c(4, 6, 6, 7.5))
    ggpi + geom_magnify(aes(from = Species == "setosa" & Sepal.Length < 5), 
                        to = c(4, 6, 6, 7.5))
  9. Configure projection lines and borders

    master

    geom_magnify() can draw lines or shading between the original area and the inset.

    • Line Styles (proj):
      • proj = "facing" (default): Standard projection lines.
      • proj = "corresponding": Always projects corner to corner.
      • proj = "single": Draws only one projection line.
    • Visuals:
      • colour: Sets the color of the borders and projection lines.
      • linewidth: Sets the thickness of the lines.
      • proj.linetype: Sets the linetype for projection lines.
      • proj.fill: Sets a color/alpha to fill the area between the projection lines (e.g., proj.fill = alpha("yellow", 0.2)).
    • Axes: Use axes = "xy" to include the x and y axes in the magnified inset.
    # Example with projection lines and axes
    ggp + 
      scale_x_continuous(labels = NULL) + 
      geom_magnify(from = from, to = to, axes = "xy", 
                   colour = "darkgreen", linewidth = 0.5, proj.linetype = 3)
  10. Recompute statistical layers in the inset

    master

    By default, geom_magnify() uses the statistical transformations (like smoothers or densities) calculated for the original plot. If you want the inset to recalculate these statistics based specifically on the zoomed-in data range, set recompute = TRUE.

    # Recalculates the smooth (e.g., loess) specifically for the inset area
    ggp2 + geom_magnify(
      from = c(-1.25, 1.25, -1, 1), 
      to = c(2, 5, 1, 5),
      recompute = TRUE
    )
  11. Customize insets with the plot argument and inset_theme()

    master

    For complex or highly customized insets, use the plot argument in geom_magnify() to pass an explicit ggplot object. To ensure the inset looks appropriate (e.g., adjusting backgrounds or margins), use inset_theme() on the plot object you intend to use as the inset.

    # 1. Create the custom inset plot
    booms_inset <- booms + 
      geom_point(data = faithful, color = "red", ...) + 
      coord_cartesian(expand = FALSE) + 
      inset_theme()
    
    # 2. Pass it to geom_magnify
    booms + geom_magnify(
      from = c(78, 90, 4.0, 4.8), 
      to = c(70, 90, 1.7, 3.3),
      plot = booms_inset
    )
  12. Create a basic magnified inset with geom_magnify()

    master

    Use geom_magnify(from, to) to create an inset of a specific area in a ggplot2 object.

    • from: A vector defining the area to magnify. For a rectangle, use c(xmin, xmax, ymin, ymax). You can also map this inside aes() to select points based on data.
    • to: A vector defining the location and size of the inset. For a rectangle, use c(xmin, xmax, ymin, ymax).

    Note: The names xmin, xmax, ymin, and ymax are optional in these vectors.

    library(ggplot2)
    library(ggmagnify)
    
    ggp <- ggplot(dv, aes(Position, NegLogP)) + 
      geom_point(color = "darkblue", alpha = 0.8, size = 0.8) + 
      labs(title = "GWAS p-values for cognitive function",
           subtitle = "Davies et al. (2018).", y = "-log(p)")
    
    from <- c(xmin = 9.75e7, xmax = 9.95e7, ymin = 16, ymax = 28)
    to <- c(2e8 - 2e7, 2e8 + 2e7, 10, 26)
    
    ggp + geom_magnify(from = from, to = to)