Skip to contents

Functions position_dodgenudge_to() and position_dodge2nudge_to() are meant to complement position_dodge() and position_dodge2() from 'ggplot2', adding as a second action that of position_nudge_to(). These positions are generally useful for adjusting the position of labels or text. As with other position functions in this package, the original positions are preserved to allow the text or labels to be linked back to their original position with a segment or arrow.

Usage

position_dodgenudge_to(
  width = 1,
  preserve = c("total", "single"),
  x = NULL,
  y = NULL,
  x.action = c("none", "spread"),
  y.action = c("none", "spread"),
  x.distance = "equal",
  y.distance = "equal",
  x.expansion = 0,
  y.expansion = 0,
  kept.origin = c("dodged", "original", "none")
)

position_dodge2nudge_to(
  width = 1,
  preserve = c("total", "single"),
  padding = 0.1,
  reverse = FALSE,
  x = NULL,
  y = NULL,
  x.action = c("none", "spread"),
  y.action = c("none", "spread"),
  x.distance = "equal",
  y.distance = "equal",
  x.expansion = 0,
  y.expansion = 0,
  kept.origin = c("dodged", "original", "none")
)

Arguments

width

Dodging width, when different to the width of the individual elements. This is useful when you want to align narrow geoms with wider geoms. See the examples.

preserve

Should dodging preserve the total width of all elements at a position, or the width of a single element?.

x, y

Coordinates of the destination position. A vector of mode numeric, that is extended if needed, to the same length as rows there are in data. The default, NULL, leaves the original coordinates unchanged after dodging.

x.action, y.action

character string, one of "none", or "spread". With "spread" distributing the positions within the range of argument x or y, if non-null, or the range the variable mapped to x or y, otherwise.

x.distance, y.distance

character or numeric Currently only "equal" is implemented.

x.expansion, y.expansion

numeric vectors of length 1 or 2, as a fraction of width of the range.

kept.origin

One of "original", "dodged" or "none".

padding

Padding between elements at the same position. Elements are shrunk by this proportion to allow space between them. Defaults to 0.1.

reverse

If TRUE, will reverse the default stacking order. This is useful if you're rotating both the plot and legend.

Value

A "Position" object.

Details

These positions apply sequentially two actions, in the order they appear in their names. The applied dodge is similar to that by position_dodge and position_dodge2 while nudging is different to that by position_nudge and equal to that applied by position_nudge_to.

The dodged and nudged to x and/or y values replace the original ones in data, while the original or the dodged coordinates are returned in x_orig and y_orig. Nudge values supported are those of mode numeric, thus including dates and times when they match the mapped data.

If the length of x and/or y is more than one but less than rows are present in the data, the vector is both recycled and reordered so that the nudges are applied sequentially based on the data values. If their length matches the number of rows in data, they are assumed to be already in data order.

The intended use is to label dodged bars, boxplots or points with labels aligned. In this case, it is mandatory to use the same argument to width when passing position_dodge() to geom_col() and position_dodgenudge_to() to geom_text(), geom_label(), geom_text_s(), geom_label_s() or their repulsive equivalents from package 'ggrepel'. Otherwise the arrows or segments will fail to connect to the labels.

When applying dodging, the return of original positions instead of the dodged ones is achieved by passing origin = "original" instead of the default of origin = "dodged".

Note

Irrespective of the action, the ordering of rows in data is preserved.

Examples


df <- data.frame(
  x = c(1,3,2,5,4,2.5),
  y = c(2, 3, 2.5, 1.8, 2.8, 1.5),
  grp = c("A", "A", "A", "B", "B", "B"),
  grp.inner = c("a", "b", "c", "a", "b", "c"),
  label = c("abc","cd","d","c","bcd","a")
)

# default is no nudging
ggplot(df, aes(grp, y, label = label, fill = label)) +
  geom_col(position = position_dodge(width = 0.92)) +
  geom_text(position = position_dodgenudge_to(width = 0.92),
            vjust = -0.2) +
  theme(legend.position = "none")


ggplot(df, aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge(width = 0.92)) +
  geom_text(position = position_dodgenudge_to(width = 0.92),
            vjust = -0.2)


ggplot(df, aes(grp, y, label = label, fill = label)) +
  geom_col(position = position_dodge2(width = 0.92)) +
  geom_text(position = position_dodge2nudge_to(width = 0.92),
            vjust = -0.2) +
  theme(legend.position = "none")


ggplot(df, aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge2(width = 0.92)) +
  geom_text(position = position_dodge2nudge_to(width = 0.92),
            vjust = -0.2)


# nudging all labels to a given y value
ggplot(df, aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge(width = 0.92)) +
  geom_text(position = position_dodgenudge_to(width = 0.92, y = 0.8))


ggplot(df, aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge2(width = 0.92)) +
  geom_text(position = position_dodge2nudge_to(width = 0.92, y = 0.8))


ggplot(df, aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge(width = 0.92)) +
  geom_text(position = position_dodgenudge_to(width = 0.92, y = 0.8))


ggplot(df[-1, ], aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge(width = 0.92)) +
  geom_text(position = position_dodgenudge_to(width = 0.92, y = 0.8))


ggplot(df[-1, ], aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge(width = 0.92, preserve = "total")) +
  geom_text(position = position_dodgenudge_to(width = 0.92, y = 0.8,
                                              preserve = "total"))


ggplot(df[-1, ], aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge(width = 0.92, preserve = "single")) +
  geom_text(position = position_dodgenudge_to(width = 0.92, y = 0.8,
                                              preserve = "single"))


ggplot(df[-1, ], aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge2(width = 0.92, preserve = "total")) +
  geom_text(position = position_dodge2nudge_to(width = 0.92, y = 0.8,
                                              preserve = "total"))


ggplot(df[-1, ], aes(grp, y, label = label, fill = grp.inner)) +
  geom_col(position = position_dodge2(width = 0.92, preserve = "single")) +
  geom_text(position = position_dodge2nudge_to(width = 0.92, y = 0.8,
                                              preserve = "single"))