Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to properly align text in radial plot in R

I have this data below:

data_melted <- structure(list(variable = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), levels = c("SJLIFE", "CCSS"), class = "factor"), 
    SN_types = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 1L, 2L, 
    3L, 4L, 5L, 6L, 7L), levels = c("Any SN", "SMN", "NMSC", 
    "Breast cancer", "Thyroid cancer", "Meningioma", "Sarcoma"
    ), class = "factor"), AF_by = c("Combined", "Combined", "Combined", 
    "Combined", "Combined", "Combined", "Combined", "Combined", 
    "Combined", "Combined", "Combined", "Combined", "Combined", 
    "Combined"), value = c(0.536, 0.467, 0.688, 0.704, 0.866, 
    0.423, 0.316, 0.435, 0.323, 0.577, 0.743, 0.664, 0.444, 0.362
    ), new_value = c(54, 47, 69, 70, 87, 42, 32, 44, 32, 58, 
    74, 66, 44, 36)), row.names = c(6L, 12L, 18L, 24L, 30L, 36L, 
42L, 48L, 54L, 60L, 66L, 72L, 78L, 84L), class = "data.frame")

I am using this code which makes the plot. However, I am having difficulty aligning the text properly around the bars. I want the text right on top of each bar 90 degree to each bar maintaining the angular position of the radial plot. How do I do it?

angle_increment.AF <- 360 / 14
angle_increment.SN_type <- 360 / 7    
ggplot(data_melted, aes(x = SN_types, y = new_value, fill = variable, label = new_value)) +
      geom_bar(stat = "identity", position = position_dodge(width = 0.9)) +
      geom_vline(xintercept = seq(1.5, 19.5, by = 3), color = "black", linetype = "dashed") + # If you want to include a vertical line
      geom_hline(yintercept = 100) +
      geom_text(aes(angle = 0 + (angle_increment.AF * (as.numeric(as.factor(SN_types)) - 1))),  # Adjust angle of text labels
                position = position_dodge(width = 1), vjust = 0.9, size = 5, color = "black") +  # Adjust label position and size
      scale_fill_manual(values = c(darker_sjlife, darker_ccss), labels = c("SJLIFE", "CCSS")) +  # Specify colors for SJLIFE and CCSS bars
      scale_y_continuous(breaks = seq(0, 100, by = 10)) +  # Custom grid lines from 0 to 1 by 0.25
      coord_polar() +
      theme_minimal() +
      theme(panel.grid.major.y = element_line(color = "gray", linetype = "dotted"),  # Adjust major grid lines
            panel.grid.minor = element_blank(),  # Remove minor grid lines
            axis.line = element_blank(),   # Remove axis lines
            axis.text.x = element_text(hjust = 0.5, angle = angle_increment, color = "black"),  # Center SN type labels within grid
            axis.text = element_text(size = 12, color = "black"),  # Adjust axis text size
            axis.title = element_text(size = 14, color = "black"),  # Adjust axis title size
            legend.title = element_text(size = 14, color = "black"),  # Adjust legend title size
            legend.text = element_text(size = 12, color = "black")) +  # Adjust legend text size
      labs(title = "",
           x = NULL, y = "(%)",
           fill = "Cohort")

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You are making this far harder than you need to. Using coord_curvedpolar from the geomtextpath package will nicely arrange the radial labels. You can also use geom_textpath in place of geom_text so that you don’t need to calculate the angles of the labels.

library(geomtextpath)

ggplot(data_melted, aes(x = SN_types, y = new_value, 
                        fill = variable, label = new_value)) +
  geom_col(position = position_dodge(width = 0.9)) +
  geom_vline(xintercept = seq(1.5, 19.5, by = 3), linetype = "dashed") +
  geom_textpath(position = position_dodge(width = 1), vjust = 1, size = 5) + 
  scale_fill_manual(values = c('deepskyblue4', 'orangered'), 
                    labels = c("SJLIFE", "CCSS")) + 
  scale_y_continuous(breaks = seq(0, 100, by = 10)) + 
  coord_curvedpolar() +
  theme_minimal() +
  theme(panel.grid.major.y = element_line(color = "gray", linetype = "dotted"), 
        panel.grid.minor = element_blank(),
        axis.line = element_blank(),  
        axis.text = element_text(size = 12, color = "black"), 
        axis.title = element_text(size = 14, color = "black"), 
        legend.title = element_text(size = 14, color = "black"), 
        legend.text = element_text(size = 12, color = "black")) + 
  labs(x = NULL, y = "(%)", fill = "Cohort")

enter image description here

Note that you didn’t include the definition of the colors darker_sjlife or darker_ccss so I have just chosen a couple of random colors to replace them.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading