Home > Software design >  How to set a conditional size scale based on name in ggplot?
How to set a conditional size scale based on name in ggplot?

Time:01-13

Below is a simple bubble plot for three character traits (Lg_chr, Mid_chr, and Sm_chr) across three locations. All good, except that because the range of Lg_chr is several orders of magnitude larger than the ranges for the other two traits, it swamps out the area differences between the smaller states, making the differences very difficult to see - for example, the area of the points for for Location_3's Mid_chr (70) and Sm_chr (5), look almost the same. Is there a way to set a conditional size scale based on name in ggplot2 without having to facit wrap them? Maybe a conditional statement for scale_size_continuous(range = c(<>, <>)) separately for Lg_chr, Mid_chr, and Sm_chr?

enter image description here

test_df = data.frame(lg_chr = c(100000, 150000, 190000),
                     mid_chr = c(50, 90, 70),
                     sm_chr = c(15, 10, 5), 
                     names = c("location_1", "location_2", "location_3"))

#reformat for graphing
test_df_long<- test_df %>% pivot_longer(!names,
  names_to = c("category"),
  values_to = "value")

#plot
ggplot(test_df_long,
       aes(x = str_to_title(category), 
           y = str_to_title(names),
           colour = str_to_title(names),
           size = value))  
  geom_point()  
  geom_text(aes(label = value), 
            colour = "white", 
            size = 3)  
  scale_x_discrete(position = "top")  
  scale_size_continuous(range = c(10, 50))   
  scale_color_manual(values = c("blue", "red",
                                "orange"))   
  labs(x = NULL, y = NULL)  
  theme(legend.position = "none",
        panel.background = element_blank(),
        panel.grid = element_blank(),
        axis.ticks = element_blank()) ```

CodePudding user response:

Edit:

You could use ggplot_build to manually modify the point layer [[1]] to specify the sizes of your points like this:

#plot
p <- ggplot(test_df_long,
       aes(x = str_to_title(category), 
           y = str_to_title(names),
           colour = str_to_title(names),
           size = value))  
  geom_point()  
  geom_text(aes(label = value), 
            colour = "white", 
            size = 3)  
  scale_x_discrete(position = "top")  
  scale_color_manual(values = c("blue", "red",
                                      "orange"))   
                                        labs(x = NULL, y = NULL)  
  theme(legend.position = "none",
        panel.background = element_blank(),
        panel.grid = element_blank(),
        axis.ticks = element_blank())

q <- ggplot_build(p)

q$data[[1]]$size <- c(7,4,1,8,5,2,9,6,3)*5

q <- ggplot_gtable(q)

plot(q)

Output:

enter image description here


You could use scale_size with a log10 scale to make the difference more visuable like this:

#plot
ggplot(test_df_long,
       aes(x = str_to_title(category), 
           y = str_to_title(names),
           colour = str_to_title(names),
           size = value))  
  geom_point()  
  geom_text(aes(label = value), 
            colour = "white", 
            size = 3)  
  scale_size(trans="log10", range = c(10, 50))   
  scale_x_discrete(position = "top")  
  scale_color_manual(values = c("blue", "red",
                                      "orange"))   
                                        labs(x = NULL, y = NULL)  
  theme(legend.position = "none",
        panel.background = element_blank(),
        panel.grid = element_blank(),
        axis.ticks = element_blank())

Output:

enter image description here

  • Related