| Title: | Create a Magnified Inset of Part of a "Ggplot" Object |
|---|---|
| Description: | Creates a magnified inset of a ggplot, with projection lines and borders around the target area and inset, plus optional shadow. Rectangular, elliptical or arbitrary regions can be magnified. Works with facets and maps. Geoms can optionally be recomputed within the inset area. |
| Authors: | David Hugh-Jones [aut, cre] |
| Maintainer: | David Hugh-Jones <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.4.2 |
| Built: | 2026-05-26 23:11:04 UTC |
| Source: | https://github.com/hughjonesd/ggmagnify |
geom_magnify() creates a magnified inset of part of a ggplot. Optional
borders are drawn around the target and inset, along with projection lines
from one to the other. from gives the location of the target area,
and to gives the location of the inset. Usually, these are specified as
c(xmin, xmax, ymin, ymax).
geom_magnify( mapping = NULL, data = NULL, stat = StatMagnify, position = "identity", ..., shape = c("rect", "ellipse", "outline"), expand = 0.1, aspect = c("free", "fixed"), axes = "", proj = c("facing", "corresponding", "single"), shadow = FALSE, corners = 0, colour = "black", linetype = 1, target.linetype = linetype, inset.linetype = linetype, proj.linetype = 2, alpha = 1, linewidth = 0.4, proj.fill = NULL, plot = NULL, shadow.args = list(sigma = 5, colour = "grey40", x_offset = 5, y_offset = 5), recompute = FALSE, scale.inset = 1, proj.combine = TRUE, na.rm = FALSE, inherit.aes = TRUE ) geom_magnify_tile( mapping = NULL, data = NULL, stat = StatMagnifyTile, position = "identity", ..., shape = c("rect", "ellipse", "outline"), expand = 0.1, aspect = c("free", "fixed"), axes = "", proj = "facing", shadow = FALSE, corners = 0, colour = "black", linetype = 1, target.linetype = linetype, inset.linetype = linetype, proj.linetype = 2, alpha = 1, linewidth = 0.4, proj.fill = NULL, plot = NULL, shadow.args = list(sigma = 5, colour = "grey40", x_offset = 5, y_offset = 5), recompute = FALSE, scale.inset = 1, proj.combine = TRUE, na.rm = FALSE, inherit.aes = FALSE )geom_magnify( mapping = NULL, data = NULL, stat = StatMagnify, position = "identity", ..., shape = c("rect", "ellipse", "outline"), expand = 0.1, aspect = c("free", "fixed"), axes = "", proj = c("facing", "corresponding", "single"), shadow = FALSE, corners = 0, colour = "black", linetype = 1, target.linetype = linetype, inset.linetype = linetype, proj.linetype = 2, alpha = 1, linewidth = 0.4, proj.fill = NULL, plot = NULL, shadow.args = list(sigma = 5, colour = "grey40", x_offset = 5, y_offset = 5), recompute = FALSE, scale.inset = 1, proj.combine = TRUE, na.rm = FALSE, inherit.aes = TRUE ) geom_magnify_tile( mapping = NULL, data = NULL, stat = StatMagnifyTile, position = "identity", ..., shape = c("rect", "ellipse", "outline"), expand = 0.1, aspect = c("free", "fixed"), axes = "", proj = "facing", shadow = FALSE, corners = 0, colour = "black", linetype = 1, target.linetype = linetype, inset.linetype = linetype, proj.linetype = 2, alpha = 1, linewidth = 0.4, proj.fill = NULL, plot = NULL, shadow.args = list(sigma = 5, colour = "grey40", x_offset = 5, y_offset = 5), recompute = FALSE, scale.inset = 1, proj.combine = TRUE, na.rm = FALSE, inherit.aes = FALSE )
mapping, data, stat, position, ..., na.rm
|
See e.g. |
shape |
Shape of the area to be magnified. |
expand |
Number. Expand the target area and inset proportionally by this amount. |
aspect |
String. |
axes |
String. Which axes to plot in the inset? |
proj |
String. What style of projection lines to draw? |
shadow |
Logical. Draw a shadow behind the inset plot? Requires the "ggfx" package. |
corners |
Numeric between 0 and 1. Radius of rounded corners for the
target area and inset. Only used if |
linetype, colour, alpha, linewidth
|
Linetype, colour, alpha and linewidth for borders and projection lines. |
target.linetype, inset.linetype, proj.linetype
|
Linetypes
for specific components. Set to |
proj.fill |
Colour to fill between the projection lines. |
plot |
Ggplot object to plot in the inset. If |
shadow.args |
List. Arguments to |
recompute |
Logical. If |
scale.inset |
Length 1 or 2 numeric. Normally, exactly the target area is shown on the inset. Sometimes you may wish to rescale the plot in the inset. Use 2 numbers to scale width and height separately. |
proj.combine |
Logical. How to draw projection lines when more than
one polygon/map area is magnified? |
inherit.aes |
If |
geom_magnify understand the following aesthetics (required aesthetics are in bold):
from
to
from and to can be vectors of length 4, like list(xmin, xmax, ymin, ymax).
These specify the bottom left and top right corners of the target area to
magnify, and the area for the magnified inset. The lists can optionally be
named: list(xmin = 1, xmax = 2, ymin = 3, ymax = 4).
Note: it is correct to use a list() for from and to, because x and
y scales may be different types, e.g. if x is a Date. However,
if x and y are both the same type, you may safely use c() instead of list().
Note: very early versions of ggmagnify used a
different order of coordinates: list(xmin, ymin, xmax, ymax).
Alternatively, from can be:
A data frame of points with two columns for x and y, or a grid::grob()
object. Points within the grob region (a polygon spanned by the data frame)
will be magnified. Points should be
on the same scale as the data, with default.units = "native" in the grob.
shape will be ignored.
A logical vector. Points in the data where from is TRUE will be
surrounded by a rectangle, ellipse or outline.
Normally you'll set from and to in the call to geom_magnify(). You can
specify them as aesthetics, e.g. if you want different areas per facet. If
so, you may need to wrap them in a list() to make sure they are length one
per row of data. Only the first row per panel is used. (To magnify multiple
areas in one panel, use multiple calls to geom_magnify().)
If shape = "ellipse" an elliptical area is magnified. This may not include
all points within the target area given by from.
If shape = "outline" then a convex hull will be drawn around points in
the target area. This only works if you are using ggplot2::geom_point() or some other
geom with aesthetics x and y; or with maps constructed by e.g. ggplot2::geom_sf().
In this case "outline" magnifies exactly the map features selected by from.
proj = "corresponding" or "facing" draws projection lines from the
corners of the target to the corners of the inset.
"corresponding" always projects each corner of the target to the same
corner of the inset.
"facing" sometimes draws lines between facing corners, when this looks
cleaner.
For non-rectangular insets, "facing" and "corresponding" are the same.
"single" draws a single line from the midpoint of facing sides.
To draw no lines, set proj.linetype = 0.
geom_magnify() uses masks. This requires R version 4.1.0 or higher, and
a graphics device that supports masking. If you are using knitr, you may have
luck with the ragg_png device. If your device doesn't support masks,
only shape = "rect" will work, and the plot inset will not be clipped
to the panel area.
R graphics devices are not very predictable. My current recommendations
are: ragg_png for knitr; cairo_pdf for PDF output; RStudio AGG
backend for interactive output. Your mileage may vary.
geom_magnify() uses dark magic to deal with faceting. It may break with
older, or newer, versions of ggplot2. If you don't need faceting, and want
your code to be robust to upgrades, set options(ggmagnify.safe_mode = TRUE)
to use slightly less magic.
By design, geom_magnify() replots the original plot using new limits. It
does not directly copy the target area pixels. The advantage is that you can
e.g. add axes, plot points at an appropriate size, zoom in on data that's
invisible in the main plot, or recompute derived graphics. If you want an
exact pixel-by-pixel copy, use a different tool.
geom_magnify() may break with discrete scales. This is a limitation in
ggplot2 for now.
Find a bug? Report it at https://github.com/hughjonesd/ggmagnify/issues/.
geom_magnify_tile()geom_magnify_tile() is a version of geom_magnify() which uses different
aesthetics. Set x, width, y, height and to_x, to_width, to_y,
to_height to specify the target and inset location.
library(ggplot2) ggp <- ggplot(iris, aes(Sepal.Width, Sepal.Length, colour = Species)) + geom_point() + xlim(c(2, 6)) from <- list(2.5, 3.5, 6, 7) to <- list(4, 6, 5, 7) # Basic magnification ggp + geom_magnify(from = from, to = to) # Convex hull of points ggp + geom_magnify(aes(from = Species == "setosa"), to = c(3, 5, 6, 8), shape = "outline") # Order matters # `geom_magnify()` stores the plot when it is added to it: ggp + scale_color_brewer() + geom_magnify(from = from, to = to) # This will print the inset without the new scale: ggp + geom_magnify(from = from, to = to) + scale_color_brewer() # For more examples see https://github.com/hughjonesd/ggmagnifylibrary(ggplot2) ggp <- ggplot(iris, aes(Sepal.Width, Sepal.Length, colour = Species)) + geom_point() + xlim(c(2, 6)) from <- list(2.5, 3.5, 6, 7) to <- list(4, 6, 5, 7) # Basic magnification ggp + geom_magnify(from = from, to = to) # Convex hull of points ggp + geom_magnify(aes(from = Species == "setosa"), to = c(3, 5, 6, 8), shape = "outline") # Order matters # `geom_magnify()` stores the plot when it is added to it: ggp + scale_color_brewer() + geom_magnify(from = from, to = to) # This will print the inset without the new scale: ggp + geom_magnify(from = from, to = to) + scale_color_brewer() # For more examples see https://github.com/hughjonesd/ggmagnify
Create a grob from a subset of sf data
grob_where(where, sf, crs = NULL)grob_where(where, sf, crs = NULL)
where |
Logical condition to be evaluated in |
sf |
An object of class sf. |
crs |
Optional coordinate reference system. |
A grid::grob() which you can pass to from.
library(ggplot2) if (requireNamespace("sf", quietly = TRUE) && requireNamespace("maps", quietly = TRUE)) { usa <- sf::st_as_sf(maps::map("state", fill=TRUE, plot = FALSE)) texas <- grob_where(ID == "texas", usa, crs = sf::st_crs(4326)) ggplot(usa) + coord_sf(crs = sf::st_crs(4326)) + geom_sf() + geom_magnify(from = texas, to = c(-90, -70, 25, 35), colour = "red", aspect = "fixed", expand = 0) }library(ggplot2) if (requireNamespace("sf", quietly = TRUE) && requireNamespace("maps", quietly = TRUE)) { usa <- sf::st_as_sf(maps::map("state", fill=TRUE, plot = FALSE)) texas <- grob_where(ID == "texas", usa, crs = sf::st_crs(4326)) ggplot(usa) + coord_sf(crs = sf::st_crs(4326)) + geom_sf() + geom_magnify(from = texas, to = c(-90, -70, 25, 35), colour = "red", aspect = "fixed", expand = 0) }
Use inset_theme() to add a suitable theme to a manually-created inset
plot. Use inset_blanks() to customize the default list of elements to
blank in the inset.
inset_theme( blank = inset_blanks(axes = axes), axes = c("", "x", "y", "xy"), margin = if (axes == "") 0 else 8 ) inset_blanks(..., axes = c("", "x", "y", "xy"))inset_theme( blank = inset_blanks(axes = axes), axes = c("", "x", "y", "xy"), margin = if (axes == "") 0 else 8 ) inset_blanks(..., axes = c("", "x", "y", "xy"))
blank |
Character vector of theme elements to blank. See |
axes |
String. Which axes to plot in the inset? |
margin |
Margin around the plot. See |
... |
Character vector of extra elements to blank. |
inset_theme() returns a ggplot theme object. inset_blanks()
returns a character vector of theme element names.
library(ggplot2) ggp <- ggplot(iris, aes(Sepal.Width, Sepal.Length, colour = Species)) + geom_point() + xlim(c(2, 6)) from <- list(2.5, 3.5, 6, 7) to <- list(4, 6, 5, 7) blanks <- inset_blanks("panel.grid") inset <- ggp + geom_density2d() + inset_theme(axes = "", blank = blanks) ggp + geom_magnify(from = from, to = to, plot = inset)library(ggplot2) ggp <- ggplot(iris, aes(Sepal.Width, Sepal.Length, colour = Species)) + geom_point() + xlim(c(2, 6)) from <- list(2.5, 3.5, 6, 7) to <- list(4, 6, 5, 7) blanks <- inset_blanks("panel.grid") inset <- ggp + geom_density2d() + inset_theme(axes = "", blank = blanks) ggp + geom_magnify(from = from, to = to, plot = inset)
Helper functions to find rectangles or convex hulls of data
rect_around(x, y, data = NULL, expand = 0) hull_around(x, y, data = NULL, expand = 0)rect_around(x, y, data = NULL, expand = 0) hull_around(x, y, data = NULL, expand = 0)
x, y
|
Unquoted names or expressions |
data |
A data frame |
expand |
Amount to expand the data around its midpoint. Default is 10 per cent. |
rect_around() returns a list with names xmin, xmax, ymin,
and ymax. hull_around() returns a data frame with columns x and y.
library(ggplot2) to <- c(2, 4.5, 6, 8) setosas <- iris[iris$Species == "setosa", ] rect_around(Sepal.Width, Sepal.Length, data = setosas) hull_around(Sepal.Width, Sepal.Length, data = setosas)library(ggplot2) to <- c(2, 4.5, 6, 8) setosas <- iris[iris$Species == "setosa", ] rect_around(Sepal.Width, Sepal.Length, data = setosas) hull_around(Sepal.Width, Sepal.Length, data = setosas)