Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log-scale minor tick marks on outside of the axis line with annotation_logticks or alternative

Tags:

r

ggplot2

annotation_logticks() is a great little function that adds minor tick marks to a log-scale axis , as shown here.

By default, the function draws ticks on the inside of the panel area of the plot. E.g., if on the y-axis, ticks appear on the right side of the axis line; if on the x-axis, ticks appear above the axis line.

example from ggplot2 website

I find this default undesirable for most plotting situations. Until now I have not found a simple way to get these minor ticks to display on the outside of the panel area where regular ggplot2 ticks appear. So for example on the y-axis appearing on the left side of the line instead of the right. Is there a straightforward solution to this?

For plotting situations where interpolating the values between major ticks is important it would be a very good option to have these appear on the left side where the regular ggplot2 labels and ticks normally appear. I haven't found a solution yet that does not involve clipping or abandoning annotation_logticks() altogether, and I haven;t been successful simply using a negative value for the tick mark length.

Here is the code directly from the ggplot2 website example:

a <- ggplot(msleep, aes(bodywt, brainwt)) +
 geom_point(na.rm = TRUE) +
 scale_x_log10(
   breaks = scales::trans_breaks("log10", function(x) 10^x),
   labels = scales::trans_format("log10", scales::math_format(10^.x))
 ) +
 scale_y_log10(
   breaks = scales::trans_breaks("log10", function(x) 10^x),
   labels = scales::trans_format("log10", scales::math_format(10^.x))
 ) +
 theme_bw()

a + annotation_logticks()

I am looking for a result that simply flips the ticks to the other side of the axis line.

like image 627
MasonK Avatar asked Mar 05 '23 17:03

MasonK


1 Answers

I found a tidy way to take care of this, though this solution does not have the same tick length as with annotation_logticks()

logticks <- function(datavar,type) {

  minimum <- 1/10^abs(floor(log10(min(datavar, na.rm=TRUE))))
  maximum <- 1*10^abs(floor(log10(max(datavar, na.rm=TRUE)))+1)
  multiple <- floor(log10(maximum/minimum))

  yourtickvector <- c()

  if (type=="breaks") {

    yourtickvector <- c(minimum)

    for (x in seq(0,multiple)) {

      andadd <- seq(minimum*10^x,minimum*10^(x+1),minimum*10^x)[-1]

      yourtickvector <- c(yourtickvector,andadd)

    }

  } else if (type=="labels") {

    for (x in seq(0,multiple)) {

      andadd <- c(minimum*10^x,rep("",8))

      yourtickvector <- c(yourtickvector,andadd)

    }

    yourtickvector <- c(yourtickvector,minimum*10^multiple)

  }

  return(yourtickvector)

}

# only changed the breaks / label fields below to call the above function

a <- ggplot(msleep, aes(bodywt, brainwt)) +
  geom_point(na.rm = TRUE) +
  scale_x_log10(
    breaks = logticks(msleep$bodywt,"breaks"),
    labels = logticks(msleep$bodywt,"labels")
  ) +
  scale_y_log10(
    breaks = logticks(msleep$brainwt,"breaks"),
    labels = logticks(msleep$brainwt,"labels")
  ) +
  theme_bw()

a

enter image description here

like image 193
Justapigeon Avatar answered Mar 09 '23 10:03

Justapigeon