r4ndomw4lk
r4ndomw4lk

Reputation: 573

Plotly R: setting the spacing between axis label and axis ticks labels

Is there any way to set a spacing between axis labels and axis ticks labels other than changing margins?

Example plot:

plot_ly(mtcars, x = ~ wt, y = ~ paste0(hp, '0000'))

As in the example plot above the title of the y axis is overlapping tick labels of this axis. Is there a way to set a spacing between them?

Upvotes: 16

Views: 22460

Answers (5)

Salim B
Salim B

Reputation: 2719

Recommended solution

Since plotly v4.9.2 you can use the new standoff layout attribute which

Sets the standoff distance (in px) between the axis labels and the title text The default value is a function of the axis tick labels, the title font.size and the axis linewidth. Note that the axis title position is always constrained within the margins, so the actual standoff distance is always less than the set or default value. By setting standoff and turning on automargin, plotly.js will push the margins to fit the axis title at given standoff distance.

Example:

plotly::plot_ly(mtcars, x = ~ wt, y = ~ paste0(hp, '0000')) %>%
  plotly::layout(yaxis = list(title = list(text = "Gross horsepower",
                                           standoff = 40L)))

enter image description here


Obsolete Workaround

Problem

Increasing the left margin as @Codutie suggests in his answer does help to a certain degree only (at least in plotly v4.7.1+). Most of the 150 pixel margin on the left is wasted space as can be seen in the screenshot below: enter image description here

R-code to generate the above plot (from @Codutie):

library(plotly)

plot_ly(mtcars, x = ~ wt, y = ~ paste0(hp, '0000')) %>%
  layout(margin = list(l = 150, r = 20, b = 10, t = 10))

Due to Plotly's goal of being responsive, it does a lot of the layout scaling automatically – which generally is a good thing IMHO because you don't have to fiddle around too much to get a presentable chart. Of course the results of Plotly's autoscaling aren't always perfect or exactly what you want to achieve and that's why there are plenty of dedicated (layout) attributes letting you manipulate certain aspects of your plot. Unfortunately there's no attribute to set the distance between an axis label and the axis itself (or the axis tick labels).

Solution (Workaround)

Instead you can rely on the following workaround to manipulate the distance between the axis and it's label by setting an appropriate y-axis title string:

plot_ly(mtcars, x = ~ wt, y = ~ paste0(hp, '0000')) %>%
    layout(margin = list(l = 150, r = 20, b = 10, t = 10),
           yaxis = list(title = paste0(c(rep(" ", 20),
                                         "Gross horsepower",
                                         rep(" ", 20),
                                         rep("\n ", 3)),
                                       collapse = "")))

This results in: enter image description here

Explanation of the y-axis title components:

  • rep("\n ", 3): This is the main part of the trick to increase the distance – just suffix the actual title ("Gross horsepower") with newlines and non-breaking spaces.
  • rep(" ", 20): This is an additional measure to ensure Plotly's autoscaling doesn't interfere again – wrapping the actual title in 40 non-breaking spaces (could be more/less of course). Otherwise the text Gross horsepower would be placed in between two axis ticks as soon as the plot height gets large enough to "physically" allow it – which would kinda foil our attempt to manually set the distance because we would have to use a much bigger newline-non-breaking-space combo to get the same distance again and – more importantly – the distance would depend on the plot height. In the above plot this isn't really necessary though, because there are as much y-axis ticks that you would need to display the plot with a height way beyond 1000px to reach that critical point.

Upvotes: 20

Arun Kumaar
Arun Kumaar

Reputation: 99

Use the standoff option

library(plotly)

y <- list(
  title = list(text="Y Axis",standoff=20)
)

plot_ly(mtcars, x = ~ wt, y = ~ paste0(hp, '0000'))%>%layout(yaxis=y)

Upvotes: 5

Jeffreys
Jeffreys

Reputation: 39

What I typically do is make use of the ticksuffix option which can create additional space behind a label.

layout(
      xaxis = list(title = "", automargin=T, ticksuffix = "%")
     ,yaxis = list(title = "", automargin=T, ticksuffix = "   ")
)

Upvotes: 3

George Hayward
George Hayward

Reputation: 605

The way I dealt with this in Python was to simply add a line break and then whitespace and you can essentially have a blank line that creates the separation. Hacky, but it works. You can see it in the second line.

 yaxis=go.layout.YAxis(
    title_text="<b>Number of Articles<br> </b>",
    titlefont=dict(size=12)),
    paper_bgcolor="white",
    title=go.layout.Title(
    xref="paper",
    x=0.5 
  )

Before:

Before

After:

After

Upvotes: 2

Codutie
Codutie

Reputation: 1075

you can try to modify the margins by adding them to your graph like this:

m <- list(l=150, r=20, b=10, t=10) # l = left; r = right; t = top; b = bottom
plot_ly(mtcars, x = ~ wt, y = ~ paste0(hp, '0000')) %>% layout(margin=m)

hope this helps?

Upvotes: 4

Related Questions