[R] ggplot with major and MINOR tick marks on a log scale

Rui Barradas ru|pb@rr@d@@ @end|ng |rom @@po@pt
Tue Jan 21 20:38:16 CET 2025


Às 02:18 de 21/01/2025, Sorkin, John escreveu:
> I have used ggplot to create a graph on which the y-axis is on the log scale. (see data and code, below.) I would like to add minor tick marks, which will also be on the log scale. The data and code are below. I hope somone can tell me how I can modify the ggplot code so it produces minor tick marks on a log scale.
> Thank you,
> John
>   
> PopByDayByAQIminus <- dget(
>    structure(list(Day = c("25", "25", "25", "25", "25", "25", "25",
>           "26", "26", "26", "26", "26", "26", "26", "27", "27", "27", "27",
>           "27", "27", "27", "28", "28", "28", "28", "28", "28", "28"),
>           AQI_Cat = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 1L, 2L,
>                 3L, 4L, 5L, 6L, 7L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 1L, 2L, 3L,
>                 4L, 5L, 6L, 7L), levels = c("Good", "Moderate", "Unhealthy For Some",
>                   "Unhealthy", "Very Unhealthy", "Hazardous1", "Hazardous2"),
>           class = "factor"), TotalPop = c(3751359, 35043, 4285,
>                   11581, 26241, 17456, 18406, 3654557, 153002, 29954, 8452,
>                    7719, 10687, 10430, 3654344, 104843, 57277, 24910, 15165,
>                    4680, 13582, 3116416, 516504, 149029, 29640, 33468, 10862,
>                    18882)),
>           class = "data.frame", row.names = c(NA, -28L)))
> 
> PopByDayByAQIminus
> 
> ggplot(PopByDayByAQIminus,aes(x=AQI_Cat,y=TotalPop/1000000,
>                                          group=Day,color=Day,shape=factor(Day),linetype = factor(Day)))+
>    labs(title=title,x="Air Quality Index") +
>    geom_point(size=4,alpha=0.7)+
>    geom_line(linewidth=1.5,alpha=0.3)+
>    theme(axis.text.x=element_text(angle = -15, hjust = 0))+
>    scale_y_continuous(trans='log10')
> scale_y_continuous(breaks=seq(0,4000000,by=1000000))
> 
> 
> 
> 
> 
> John David Sorkin M.D., Ph.D.
> Professor of Medicine, University of Maryland School of Medicine;
> Associate Director for Biostatistics and Informatics, Baltimore VA Medical Center Geriatrics Research, Education, and Clinical Center;
> PI Biostatistics and Informatics Core, University of Maryland School of Medicine Claude D. Pepper Older Americans Independence Center;
> Senior Statistician University of Maryland Center for Vascular Research;
> 
> Division of Gerontology and Paliative Care,
> 10 North Greene Street
> GRECC (BT/18/GR)
> Baltimore, MD 21201-1524
> Cell phone 443-418-5382
> 
> 
> 
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide https://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
Hello,

Here are two plots with y axis minor breaks tick marks.
They both use guide_axis(minor.ticks = TRUE) but the 2nd plot spaces the 
tick marks as in logarithmic paper with an auxiliary function taken from 
a StackOverflow post.

Also, instead of scale_y_continuous(trans = "log10") I have used the 
equivalent scale_y_log10(), it makes the code simpler and the effect is 
exactly the same. From ?scale_y_continuous:

"There are three variants that set the transform argument for commonly 
used transformations: ⁠scale_*_log10()⁠, ⁠scale_*_sqrt()⁠ and 
⁠scale_*_reverse()⁠."


Now the code.



PopByDayByAQIminus %>%
   mutate(Day = factor(Day)) %>%
   ggplot(
     aes(x = AQI_Cat, y = TotalPop/1000000,
         group = Day,
         color = Day,
         shape = Day,
         linetype = Day)) +
   labs(x = "Air Quality Index") +
   geom_point(size = 4,alpha = 0.7) +
   geom_line(linewidth = 1.5, alpha = 0.3) +
   theme(axis.text.x = element_text(angle = -15, hjust = 0)) +
   scale_y_log10() +
   guides(y = guide_axis(minor.ticks = TRUE))

#--- And the other plot

# function in this StackOverflow post
# https://stackoverflow.com/a/33179099/8245406
log10_minor_break = function (...){
   function(x) {
     minx         = floor(min(log10(x), na.rm=TRUE)) - 1
     maxx         = ceiling(max(log10(x), na.rm=TRUE)) + 1
     n_major      = maxx - minx + 1
     major_breaks = seq(minx, maxx, by = 1)
     minor_breaks =
       rep(log10(seq(1, 9, by=1)), times = n_major) +
       rep(major_breaks, each = 9)
     return(10^(minor_breaks))
   }
}

PopByDayByAQIminus %>%
   mutate(Day = factor(Day)) %>%
   ggplot(
     aes(x = AQI_Cat, y = TotalPop/1000000,
         group = Day,
         color = Day,
         shape = Day,
         linetype = Day)) +
   labs(x = "Air Quality Index") +
   geom_point(size = 4,alpha = 0.7) +
   geom_line(linewidth = 1.5, alpha = 0.3) +
   theme(axis.text.x = element_text(angle = -15, hjust = 0)) +
   scale_y_log10(
     minor_breaks = log10_minor_break()
   ) +
   guides(y = guide_axis(minor.ticks = TRUE))


Hope this helps,

Rui Barradas

-- 
Este e-mail foi analisado pelo software antivírus AVG para verificar a presença de vírus.
www.avg.com



More information about the R-help mailing list