Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

r

plotly

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?

like image 757
r4ndomw4lk Avatar asked Apr 05 '17 10:04

r4ndomw4lk


People also ask

How do you change the axis range in Plotly?

By default, plotly extends the range of the axis (overriding the range parameter) to fit in the figure domain . You can restrict the domain to force the axis to span only the set range, by setting constrain='domain' as below.

How do you set the axis labels and title of the R plots?

Change main title and axis labels main: the text for the main title. xlab: the text for the x axis label. ylab: the text for y axis title. sub: sub-title; It's placed at the bottom of x-axis.


5 Answers

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.
like image 73
Salim B Avatar answered Oct 04 '22 07:10

Salim B


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 = "   ")
)
like image 27
Jeffreys Avatar answered Oct 04 '22 08:10

Jeffreys


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?

like image 44
Codutie Avatar answered Oct 04 '22 06:10

Codutie


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)
like image 43
Arun Kumaar Avatar answered Oct 04 '22 06:10

Arun Kumaar


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

like image 25
George Hayward Avatar answered Oct 04 '22 07:10

George Hayward