Skip to content

use Plotly axis titles if not facetted #573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 41 additions & 27 deletions R/ggplotly.R
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,9 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
}
# type of unit conversion
type <- if (xy == "x") "height" else "width"
# get axis title
axisTitleText <- sc$name %||% p$labels[[xy]] %||% ""
if (is_blank(axisTitle)) axisTitleText <- ""
# https://plot.ly/r/reference/#layout-xaxis
axisObj <- list(
type = "linear",
Expand All @@ -360,7 +363,10 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
gridcolor = toRGB(panelGrid$colour),
gridwidth = unitConvert(panelGrid, "pixels", type),
zeroline = FALSE,
anchor = anchor
anchor = anchor,
# if not facets then use Plotly axis titling mechanism
# see https://github.com/ropensci/plotly/issues/510
title = axisTitleText
)
# convert dates to milliseconds (86400000 = 24 * 60 * 60 * 1000)
# this way both dates/datetimes are on same scale
Expand All @@ -380,27 +386,14 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A

# do some stuff that should be done once for the entire plot
if (i == 1) {
# add space for exterior facet strips in `layout.margin`
if (has_facet(p)) {
stripSize <- unitConvert(stripText, "pixels", type)
if (xy == "x") {
gglayout$margin$t <- gglayout$margin$t + stripSize
}
if (xy == "y" && inherits(p$facet, "grid")) {
gglayout$margin$r <- gglayout$margin$r + stripSize
}
}
axisTitleText <- sc$name %||% p$labels[[xy]] %||% ""
if (is_blank(axisTitle)) axisTitleText <- ""
axisTickText <- axisObj$ticktext[which.max(nchar(axisObj$ticktext))]
side <- if (xy == "x") "b" else "l"
# account for axis ticks, ticks text, and titles in plot margins
# (apparently ggplot2 doesn't support axis.title/axis.text margins)
gglayout$margin[[side]] <- gglayout$margin[[side]] + axisObj$ticklen +
bbox(axisTickText, axisObj$tickangle, axisObj$tickfont$size)[[type]] +
bbox(axisTitleText, axisTitle$angle, unitConvert(axisTitle, "pixels", type))[[type]]
# draw axis titles as annotations
# (plotly.js axis titles aren't smart enough to dodge ticks & text)

if (nchar(axisTitleText) > 0) {
axisTextSize <- unitConvert(axisText, "npc", type)
axisTitleSize <- unitConvert(axisTitle, "npc", type)
Expand All @@ -409,21 +402,42 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
bbox(axisTickText, axisText$angle, axisTextSize)[[type]] -
bbox(axisTitleText, axisTitle$angle, axisTitleSize)[[type]] / 2 -
unitConvert(theme$axis.ticks.length, "npc", type))
# npc is on a 0-1 scale of the _entire_ device,
# but these units _should_ be wrt to the plotting region
# multiplying the offset by 2 seems to work, but this is a terrible hack
offset <- 1.75 * offset
x <- if (xy == "x") 0.5 else offset
y <- if (xy == "x") offset else 0.5
gglayout$annotations <- c(
gglayout$annotations,
make_label(
faced(axisTitleText, axisTitle$face), x, y, el = axisTitle,
xanchor = "center", yanchor = "middle"
}

# add space for exterior facet strips in `layout.margin`
if (has_facet(p)) {
stripSize <- unitConvert(stripText, "pixels", type)
if (xy == "x") {
gglayout$margin$t <- gglayout$margin$t + stripSize
}
if (xy == "y" && inherits(p$facet, "grid")) {
gglayout$margin$r <- gglayout$margin$r + stripSize
}
# draw axis titles as annotations
# (plotly.js axis titles aren't smart enough to dodge ticks & text)
if (nchar(axisTitleText) > 0) {
# npc is on a 0-1 scale of the _entire_ device,
# but these units _should_ be wrt to the plotting region
# multiplying the offset by 2 seems to work, but this is a terrible hack
offset <- 1.75 * offset
x <- if (xy == "x") 0.5 else offset
y <- if (xy == "x") offset else 0.5
gglayout$annotations <- c(
gglayout$annotations,
make_label(
faced(axisTitleText, axisTitle$face), x, y, el = axisTitle,
xanchor = "center", yanchor = "middle"
)
)
)
}
}
}

if (has_facet(p)) {
# turn off plotly axis titles
# since we need special treatment for facets
gglayout[[axisName]]$title <- ""
}

} # end of axis loop

Expand Down