Draws the intercept and slope (or group differences) of a fitted model as
arrows and labels directly on the plot they describe: a rise-over-run
triangle for a continuous predictor, an arrow to each non-reference group for
a categorical one. Where gf_model() draws the fit itself, gf_b() draws
the numbers that describe it.
gf_coef() is a fully supported alias of gf_b(). The package already
exports b(), b0(), b1() as its vocabulary for coefficients, and a
reader who knows stats::coef() will look for a plot-side counterpart
under that name.
Usage
gf_b(
object = NULL,
gformula = NULL,
data = NULL,
...,
model,
color = "#b599ed",
label_color = "black",
label_size = 3.5,
arrow_linewidth = 0.5,
show_b0 = TRUE,
run = NULL,
run_x = NULL,
b0_alpha = 0.3,
b0_linewidth = 0.8,
b0_size = 4,
arrow_nudge = 0.18,
label_nudge = 0.08,
xlab,
ylab,
title,
subtitle,
caption,
geom = ggplot2::GeomSegment,
stat = "identity",
position = "identity",
show.legend = NA,
show.help = NULL,
inherit = TRUE,
environment = parent.frame()
)
gf_coef(
object = NULL,
gformula = NULL,
data = NULL,
...,
model,
color = "#b599ed",
label_color = "black",
label_size = 3.5,
arrow_linewidth = 0.5,
show_b0 = TRUE,
run = NULL,
run_x = NULL,
b0_alpha = 0.3,
b0_linewidth = 0.8,
b0_size = 4,
arrow_nudge = 0.18,
label_nudge = 0.08,
xlab,
ylab,
title,
subtitle,
caption,
geom = ggplot2::GeomSegment,
stat = "identity",
position = "identity",
show.legend = NA,
show.help = NULL,
inherit = TRUE,
environment = parent.frame()
)Arguments
- object
A plot created with the
ggformulapackage.- gformula
Not used.
gf_b()annotates a model, not an aesthetic formula; a model given positionally lands here and is moved tomodel.- data
Not used. The marks are placed from the model's own coefficients and data.
- ...
Not used. Every mark states its own geom and params; set appearance with
color,label_color,label_size,arrow_linewidth,b0_linewidth,b0_size,b0_alpha. Anything else here (alpha,linetype, ...) is warned about and dropped, because the marks are heterogeneous geoms with no single params bag to receive it.- model
The model to annotate: a fit from
lm()oraov(), with one predictor at most, and that predictor spelled the way the plot's own axis spells it –log(Height)andHeightare the same column but not the same axis, and b1 is a rise per unit of whichever one the model was fit on. It needs an intercept, because every mark here is measured from b0; a categorical predictor needs treatment coding, because every arrow is drawn as one group's difference from the reference group and no other coding's coefficients are that. Each of those is refused rather than drawn, because each would otherwise produce a picture that looks right. A formula is refused too –gf_b()'s whole output is a set of labeled numbers, and there is no fit to read them from. May be given positionally or asmodel =. Omitted, the model the plot implies is fit and annotated instead.- color, label_color
The arrows/lines and the label text.
colourandlabel_colourare accepted too. Each is a single value, not a mapping – every mark is one row computed from the coefficients, so there are no rows of data to map an aesthetic over;color = ~variableis refused.- label_size, arrow_linewidth, b0_linewidth, b0_size
Sizes for the labels, the arrows, the b0 line and the b0 dot.
- show_b0
Draw the
b0line/dot and its label, and expand the PREDICTOR's axis to include 0 on a continuous model – x on most plots, y on one that puts the outcome on x.TRUEby default; a latergf_lims()on that axis overrides the expansion and can push the b0 dot off the page.- run, run_x
The run a continuous model's rise is measured over, and the x position the triangle starts at. Both chosen from the data when left
NULL. Namingrunon a categorical model is warned about and ignored – its coefficients are group differences, not a rate.- b0_alpha
The transparency of the categorical b0 reference line.
- arrow_nudge, label_nudge
A categorical arrow's x position, and its label's offset from it, in level units (1 = one group apart). Not used on the empty model, whose one axis is a count, not a level, and whose b0 label is placed at the panel's edge instead.
- xlab, ylab, title, subtitle, caption
Labels for the plot.
- geom, stat, position
Not set by the caller. Every mark states its own geom.
- show.legend
Not used. The marks are annotations and never contribute to a legend; a non-default value is warned about and dropped.
- show.help
Print the function's own help instead of drawing.
- inherit
Not set by the caller. Every mark states its own aesthetics.
- environment
The environment mappings are resolved in.
What is drawn
A continuous predictor: a vertical rise arrow from fit(run_x) to
fit(run_x + run), a horizontal run segment at its tip, a rise label
(plotmath b1 when run is 1, otherwise run times b1), a run-distance
label under the run segment (over it, for a negative rise), and a hollow
dot at (0, b0) with a b0 label.
A categorical predictor: one horizontal reference line at b0 (the
reference level's mean), and for each level after it a segment from b0 to
b0 plus that level's coefficient, with an arrow head, labeled (plotmath)
b1, b2, … Level order is read off coef(model), so a releveled factor still
labels the arrow that matches its coefficient.
No predictor (the empty model): the b0 line and its label, nothing
else.
Every mark is a separately tagged layer – "b0", "b1", "bk_2",
"run", and each one's own "_label" – so a script can find one without
counting layers.
No model
With no model, gf_b() reads the model the plot implies – the same
decision gf_model()'s own inference reads – and fits it at call time, on
the plot's whole data. This is refused on a faceted plot, because
gf_model()'s inferred line is fit per panel and a single set of arrows
drawn over it would describe a fit no panel actually has.
Placement
Every mark is placed from the model's coefficients and from level indices, never from a drawn point's position, so jitter never moves an arrow.
show_b0 = TRUE (the default) expands the PREDICTOR's axis to include 0 on
a continuous model, because b0 is the prediction where the predictor is 0
and a picture of it that does not show that point is not a picture of b0.
Usually that is x; on a plot that puts the outcome on x it is y, and the
expansion follows the predictor rather than the letter. Calling gf_lims()
on that axis afterward overrides the expansion and can push the b0 dot off
the page.
See also
gf_model() draws the fit itself.
Examples
# continuous: b1 as a rise-over-run triangle, b0 where the line meets x = 0
height_model <- lm(Thumb ~ Height, data = Fingers)
gf_point(Thumb ~ Height, data = Fingers, alpha = .3) %>% gf_b(height_model)
# the slope per one unit
gf_point(Thumb ~ Height, data = Fingers) %>% gf_b(height_model, run = 1)
# an explicit run labels the rise "10 x b1"
gf_point(Thumb ~ Height, data = Fingers) %>% gf_b(height_model, run = 10)
# categorical: b0 is the reference group's mean, each b_k is an arrow to group k
tip_model <- lm(Tip ~ Condition, data = TipExperiment)
gf_jitter(Tip ~ Condition, data = TipExperiment, width = .1) %>% gf_b(tip_model)
# no model: the model the plot implies, on the values the plot drew
set.seed(1)
gf_jitter(shuffle(Height) ~ Sex, data = Fingers, width = .1) %>%
gf_model() %>%
gf_b()
# gf_coef() is the same function under the name coef() readers look for
flipper_model <- lm(body_mass_kg ~ flipper_length_m, data = penguins)
gf_point(body_mass_kg ~ flipper_length_m, data = penguins) %>%
gf_coef(flipper_model)