Skip to content

Commit d136b69

Browse files
committed
Merge pull request #574 from ropensci/fix/axis-labels
use Plotly axis titles if not facetted
2 parents e449e3c + b128922 commit d136b69

File tree

6 files changed

+60
-37
lines changed

6 files changed

+60
-37
lines changed

DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: plotly
22
Title: Create Interactive Web Graphics via 'plotly.js'
3-
Version: 3.5.4
3+
Version: 3.5.5
44
Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"),
55
email = "[email protected]"),
66
person("Chris", "Parmer", role = c("aut", "cph"),

NEWS

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
3.5.5 -- 5 May 2016
2+
3+
CHANGES:
4+
5+
ggplotly() will now use plotly's layout.axisid.title (instead of
6+
layout.annotations) for axis titles on non-faceted plots.
7+
This will make for a better title placement experience (see #510).
8+
9+
BUG FIX:
10+
11+
Space for interior facet_wrap() strips are now accounted for.
12+
113
3.5.4 -- 5 May 2016
214

315
BUG FIX:

R/ggplotly.R

+41-30
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
277277
theme[["strip.text.x"]] %||% theme[["strip.text"]],
278278
"npc", "height"
279279
)
280+
panelMarginY <- panelMarginY + stripSize
280281
# space for ticks/text in free scales
281282
if (p$facet$free$x) {
282283
axisTicksX <- unitConvert(
@@ -307,7 +308,6 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
307308
rep(panelMarginX, 2),
308309
rep(panelMarginY, 2)
309310
)
310-
311311
doms <- get_domains(nPanels, nRows, margins)
312312

313313
for (i in seq_len(nPanels)) {
@@ -335,6 +335,9 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
335335
}
336336
# type of unit conversion
337337
type <- if (xy == "x") "height" else "width"
338+
# get axis title
339+
axisTitleText <- sc$name %||% p$labels[[xy]] %||% ""
340+
if (is_blank(axisTitle)) axisTitleText <- ""
338341
# https://plot.ly/r/reference/#layout-xaxis
339342
axisObj <- list(
340343
type = "linear",
@@ -350,7 +353,7 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
350353
ticklen = unitConvert(theme$axis.ticks.length, "pixels", type),
351354
tickwidth = unitConvert(axisTicks, "pixels", type),
352355
showticklabels = !is_blank(axisText),
353-
tickfont = text2font(axisText, "height"),
356+
tickfont = text2font(axisText, type),
354357
tickangle = - (axisText$angle %||% 0),
355358
showline = !is_blank(axisLine),
356359
linecolor = toRGB(axisLine$colour),
@@ -360,7 +363,9 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
360363
gridcolor = toRGB(panelGrid$colour),
361364
gridwidth = unitConvert(panelGrid, "pixels", type),
362365
zeroline = FALSE,
363-
anchor = anchor
366+
anchor = anchor,
367+
title = axisTitleText,
368+
titlefont = text2font(axisTitle)
364369
)
365370
# convert dates to milliseconds (86400000 = 24 * 60 * 60 * 1000)
366371
# this way both dates/datetimes are on same scale
@@ -380,27 +385,14 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
380385

381386
# do some stuff that should be done once for the entire plot
382387
if (i == 1) {
383-
# add space for exterior facet strips in `layout.margin`
384-
if (has_facet(p)) {
385-
stripSize <- unitConvert(stripText, "pixels", type)
386-
if (xy == "x") {
387-
gglayout$margin$t <- gglayout$margin$t + stripSize
388-
}
389-
if (xy == "y" && inherits(p$facet, "grid")) {
390-
gglayout$margin$r <- gglayout$margin$r + stripSize
391-
}
392-
}
393-
axisTitleText <- sc$name %||% p$labels[[xy]] %||% ""
394-
if (is_blank(axisTitle)) axisTitleText <- ""
395388
axisTickText <- axisObj$ticktext[which.max(nchar(axisObj$ticktext))]
396389
side <- if (xy == "x") "b" else "l"
397390
# account for axis ticks, ticks text, and titles in plot margins
398391
# (apparently ggplot2 doesn't support axis.title/axis.text margins)
399392
gglayout$margin[[side]] <- gglayout$margin[[side]] + axisObj$ticklen +
400393
bbox(axisTickText, axisObj$tickangle, axisObj$tickfont$size)[[type]] +
401394
bbox(axisTitleText, axisTitle$angle, unitConvert(axisTitle, "pixels", type))[[type]]
402-
# draw axis titles as annotations
403-
# (plotly.js axis titles aren't smart enough to dodge ticks & text)
395+
404396
if (nchar(axisTitleText) > 0) {
405397
axisTextSize <- unitConvert(axisText, "npc", type)
406398
axisTitleSize <- unitConvert(axisTitle, "npc", type)
@@ -409,22 +401,41 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
409401
bbox(axisTickText, axisText$angle, axisTextSize)[[type]] -
410402
bbox(axisTitleText, axisTitle$angle, axisTitleSize)[[type]] / 2 -
411403
unitConvert(theme$axis.ticks.length, "npc", type))
412-
# npc is on a 0-1 scale of the _entire_ device,
413-
# but these units _should_ be wrt to the plotting region
414-
# multiplying the offset by 2 seems to work, but this is a terrible hack
415-
offset <- 1.75 * offset
416-
x <- if (xy == "x") 0.5 else offset
417-
y <- if (xy == "x") offset else 0.5
418-
gglayout$annotations <- c(
419-
gglayout$annotations,
420-
make_label(
421-
faced(axisTitleText, axisTitle$face), x, y, el = axisTitle,
422-
xanchor = "center", yanchor = "middle"
404+
}
405+
406+
# add space for exterior facet strips in `layout.margin`
407+
if (has_facet(p)) {
408+
stripSize <- unitConvert(stripText, "pixels", type)
409+
if (xy == "x") {
410+
gglayout$margin$t <- gglayout$margin$t + stripSize
411+
}
412+
if (xy == "y" && inherits(p$facet, "grid")) {
413+
gglayout$margin$r <- gglayout$margin$r + stripSize
414+
}
415+
# facets have multiple axis objects, but only one title for the plot,
416+
# so we empty the titles and try to draw the title as an annotation
417+
if (nchar(axisTitleText) > 0) {
418+
# npc is on a 0-1 scale of the _entire_ device,
419+
# but these units _should_ be wrt to the plotting region
420+
# multiplying the offset by 2 seems to work, but this is a terrible hack
421+
offset <- 1.75 * offset
422+
x <- if (xy == "x") 0.5 else offset
423+
y <- if (xy == "x") offset else 0.5
424+
gglayout$annotations <- c(
425+
gglayout$annotations,
426+
make_label(
427+
faced(axisTitleText, axisTitle$face), x, y, el = axisTitle,
428+
xanchor = "center", yanchor = "middle"
429+
)
423430
)
424-
)
431+
}
425432
}
426433
}
427-
434+
435+
if (has_facet(p)) {
436+
gglayout[[axisName]]$title <- ""
437+
}
438+
428439
} # end of axis loop
429440

430441
xdom <- gglayout[[lay[, "xaxis"]]]$domain

tests/testthat/test-cookbook-axes.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ no.x.title <- bp +
107107

108108
test_that("coord_fixed(ratio)", {
109109
info <- expect_traces(no.x.title, 1, "no-x-title")
110-
expect_true(length(info$layout$annotations) == 1)
110+
expect_identical(info$layout$xaxis$title, "")
111111
})
112112

113113
# Also possible to set the axis label with the scale

tests/testthat/test-ggplot-labels.R

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ test_that("ylab is translated correctly", {
1313
geom_point(aes(Petal.Width, Sepal.Width)) +
1414
ylab("sepal width")
1515
info <- save_outputs(ggiris, "labels-ylab")
16-
labs <- unlist(lapply(info$layout$annotations, "[[", "text"))
17-
expect_identical(sort(labs), c("Petal.Width", "sepal width"))
16+
labs <- c(info$layout$xaxis$title, info$layout$yaxis$title)
17+
expect_identical(labs, c("Petal.Width", "sepal width"))
1818
})
1919

2020
# TODO: why is this failing on R-devel???

tests/testthat/test-ggplot-legend.R

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ test_that("Discrete colour and shape get merged into one legend", {
3030
nms, paste0("(", d$vs, ",", d$cyl, ")")
3131
)
3232
a <- info$layout$annotations
33-
expect_match(a[[3]]$text, "^factor\\(vs\\)")
34-
expect_match(a[[3]]$text, "factor\\(cyl\\)$")
35-
expect_true(a[[3]]$y > info$layout$legend$y)
33+
expect_match(a[[1]]$text, "^factor\\(vs\\)")
34+
expect_match(a[[1]]$text, "factor\\(cyl\\)$")
35+
expect_true(a[[1]]$y > info$layout$legend$y)
3636
})
3737

3838

0 commit comments

Comments
 (0)