Skip to content

Commit bdfdc4b

Browse files
authored
Better positioning of facet axis annotations (#1975)
1 parent 1093705 commit bdfdc4b

13 files changed

+41
-32
lines changed

DESCRIPTION

-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ Suggests:
6565
webshot,
6666
listviewer,
6767
dendextend,
68-
sf,
6968
maptools,
7069
rgeos,
7170
png,

NEWS.md

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
* `ggplotly()` now uses the `layout.legend.title` (instead of `layout.annotations`) plotly.js API to convert guides for discrete scales. (#1961)
1010

11+
## Improvements
12+
13+
* `ggplotly()` now better positions axis titles for `facet_wrap()`/`facet_grid()`. (#1975)
14+
1115
# 4.9.4.1
1216

1317
## BUG FIXES

R/ggplotly.R

+27-21
Original file line numberDiff line numberDiff line change
@@ -833,11 +833,12 @@ gg2list <- function(p, width = NULL, height = NULL,
833833
gglayout[[axisName]] <- axisObj
834834

835835
# do some stuff that should be done once for the entire plot
836+
is_x <- xy == "x"
836837
if (i == 1) {
837838
# Split ticktext elements by "\n" to account for linebreaks
838839
axisTickText <- strsplit(as.character(axisObj$ticktext), split = "\n", fixed = TRUE)
839840
axisTickText <- longest_element(unlist(axisTickText))
840-
side <- if (xy == "x") "b" else "l"
841+
side <- if (is_x) "b" else "l"
841842
# account for axis ticks, ticks text, and titles in plot margins
842843
# (apparently ggplot2 doesn't support axis.title/axis.text margins)
843844
gglayout$margin[[side]] <- gglayout$margin[[side]] + axisObj$ticklen +
@@ -847,40 +848,45 @@ gg2list <- function(p, width = NULL, height = NULL,
847848
if (robust_nchar(axisTitleText) > 0) {
848849
axisTextSize <- unitConvert(axisText, "npc", type)
849850
axisTitleSize <- unitConvert(axisTitle, "npc", type)
850-
offset <-
851-
(0 -
852-
bbox(axisTickText, axisText$angle, axisTextSize)[[type]] -
853-
bbox(axisTitleText, axisTitle$angle, axisTitleSize)[[type]] / 2 -
854-
unitConvert(theme$axis.ticks.length, "npc", type))
855851
}
856852

857853
# add space for exterior facet strips in `layout.margin`
858854

859855
if (has_facet(plot)) {
860856
stripSize <- unitConvert(stripText, "pixels", type)
861-
if (xy == "x") {
857+
if (is_x) {
862858
gglayout$margin$t <- gglayout$margin$t + stripSize
863859
}
864-
if (xy == "y" && inherits(plot$facet, "FacetGrid")) {
860+
if (is_x && inherits(plot$facet, "FacetGrid")) {
865861
gglayout$margin$r <- gglayout$margin$r + stripSize
866862
}
867863
# facets have multiple axis objects, but only one title for the plot,
868864
# so we empty the titles and try to draw the title as an annotation
869865
if (robust_nchar(axisTitleText) > 0) {
870-
# npc is on a 0-1 scale of the _entire_ device,
871-
# but these units _should_ be wrt to the plotting region
872-
# multiplying the offset by 2 seems to work, but this is a terrible hack
873-
x <- if (xy == "x") 0.5 else offset
874-
y <- if (xy == "x") offset else 0.5
875-
gglayout$annotations <- c(
876-
gglayout$annotations,
877-
make_label(
878-
faced(axisTitleText, axisTitle$face), x, y, el = axisTitle,
879-
xanchor = if (xy == "x") "center" else "right",
880-
yanchor = if (xy == "x") "top" else "center",
881-
annotationType = "axis"
882-
)
866+
axisAnn <- make_label(
867+
faced(axisTitleText, axisTitle$face),
868+
el = axisTitle,
869+
x = if (is_x) 0.5 else 0,
870+
y = if (is_x) 0 else 0.5,
871+
xanchor = if (is_x) "center" else "right",
872+
yanchor = if (is_x) "top" else "center",
873+
annotationType = "axis"
883874
)
875+
876+
textMargin <- sum(axisText$margin[if (is_x) c(1, 3) else c(2, 4)])
877+
class(textMargin) <- setdiff(class(textMargin), "margin")
878+
titleMargin <- axisTitle$margin[if (is_x) 1 else 2]
879+
class(titleMargin) <- setdiff(class(titleMargin), "margin")
880+
offset <- bbox(axisTickText, axisText$angle, axisTextSize)[[type]] +
881+
unitConvert(theme$axis.ticks.length, "npc", type) +
882+
unitConvert(textMargin, "npc", type) +
883+
unitConvert(titleMargin, "npc", type)
884+
885+
offset <- unitConvert(grid::unit(offset, "npc"), "pixels", type)
886+
887+
shift <- if (is_x) "yshift" else "xshift"
888+
axisAnn[[1]][[shift]] <- -1 * offset
889+
gglayout$annotations <- c(gglayout$annotations, axisAnn)
884890
}
885891
}
886892
}

tests/testthat/_snaps/cookbook-lines/cookbook-axes-scatter-facet-hline-vline.svg

+1-1
Loading

tests/testthat/_snaps/cookbook-lines/cookbook-axes-scatter-facet-hline.svg

+1-1
Loading

tests/testthat/_snaps/cookbook-lines/cookbook-axes-scatter-facet.svg

+1-1
Loading

tests/testthat/_snaps/ggplot-facets/3-panels.svg

+1-1
Loading

tests/testthat/_snaps/ggplot-facets/barley.svg

+1-1
Loading

tests/testthat/_snaps/ggplot-facets/facet-grid-free-y.svg

+1-1
Loading

tests/testthat/_snaps/ggplot-facets/facet-grid-free.svg

+1-1
Loading

tests/testthat/_snaps/ggplot-facets/facet-wrap-free-x.svg

+1-1
Loading

tests/testthat/_snaps/ggplot-facets/facet-wrap-free-y.svg

+1-1
Loading

tests/testthat/_snaps/ggplot-facets/facet-wrap-free.svg

+1-1
Loading

0 commit comments

Comments
 (0)