[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:41:49 CET 2025


Às 19:38 de 21/01/2025, Rui Barradas escreveu:
> À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
> 
Hello,

I forgot to say that the dplyr::mutate is meant to have only one legend 
for Day. Like it was there were two of them. This is obviously not part 
of the answer to the question itself.

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