0

I want to loop my data twice to obtain the following sets of plots:

One includes background values which are similar to each other and have different vertical error bars. In this case, they overlap each other and I can't distinguish them, which is possible in another graph program. geom_jitterand position_dodge did not help. I want to clearly see all background values and their error bars.

The other one excludes background values. I want to apply an x limit that changes for every looped plot.

The dput data of a csv similar to my actual data:

structure(list(Al = c(14000, 23000, NA, 13400, 13400, 12000, 
NA, NA, 0.005), Co = c(NA, 56.7, 34.2, 180, NA, NA, NA, 25, 0.005
), Mg = c(24, 200, 90, NA, NA, 123, 98, NA, 0.005), a1 = c(0.05, 
0.12, 0.09, NA, 0.07, NA, NA, NA, NA), a2 = c(NA, NA, NA, 0.01, 
0.07, 1.08, 0.05, NA, NA), a3 = c(0.4, 1.2, 0.3, 1.1, 0.7, 1.5, 
0.25, 0.78, NA), bg_a1 = c(NA, NA, NA, NA, NA, NA, NA, NA, 0.002
), bg_a2 = c(NA, NA, NA, NA, NA, NA, NA, NA, 0.003), bg_a3 = c(NA, 
NA, NA, NA, NA, NA, NA, NA, 0.002), err_a1 = c(NA, NA, NA, NA, 
NA, NA, NA, NA, 0.0013), err_a2 = c(NA, NA, NA, NA, NA, NA, NA, 
NA, 0.007), err_a3 = c(NA, NA, NA, NA, NA, NA, NA, NA, 0.003)), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -9L), spec = structure(list(
    cols = list(Al = structure(list(), class = c("collector_double", 
    "collector")), Co = structure(list(), class = c("collector_double", 
    "collector")), Mg = structure(list(), class = c("collector_double", 
    "collector")), a1 = structure(list(), class = c("collector_double", 
    "collector")), a2 = structure(list(), class = c("collector_double", 
    "collector")), a3 = structure(list(), class = c("collector_double", 
    "collector")), bg_a1 = structure(list(), class = c("collector_double", 
    "collector")), bg_a2 = structure(list(), class = c("collector_double", 
    "collector")), bg_a3 = structure(list(), class = c("collector_double", 
    "collector")), err_a1 = structure(list(), class = c("collector_double", 
    "collector")), err_a2 = structure(list(), class = c("collector_double", 
    "collector")), err_a3 = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"))

Example data:

~Al,   ~Co,   ~Mg,  ~a1,  ~a2,  ~a3, ~bg_a1, ~bg_a2, ~bg_a3, ~err_a1, ~err_a2, ~err_a3,
  14000,    NA,    24, 0.05,   NA,  0.4,     NA,     NA,     NA,      NA,      NA,      NA,
  23000,  56.7,   200, 0.12,   NA,  1.2,     NA,     NA,     NA,      NA,      NA,      NA,
     NA,  34.2,    90, 0.09,   NA,  0.3,     NA,     NA,     NA,      NA,      NA,      NA,
  13400,   180,    NA,   NA, 0.01,  1.1,     NA,     NA,     NA,      NA,      NA,      NA,
  13400,    NA,    NA, 0.07, 0.07,  0.7,     NA,     NA,     NA,      NA,      NA,      NA,
  12000,    NA,   123,   NA, 1.08,  1.5,     NA,     NA,     NA,      NA,      NA,      NA,
     NA,    NA,    98,   NA, 0.05, 0.25,     NA,     NA,     NA,      NA,      NA,      NA,
     NA,    25,    NA,   NA,   NA, 0.78,     NA,     NA,     NA,      NA,      NA,      NA,
  0.005, 0.005, 0.005,   NA,   NA,   NA,  0.002,  0.003,  0.002,  0.0013,   0.007,   0.003

And my code, in which the background values and its error bars are commented out when I want the second set of plots with changeable x limits:

library(tidyverse)
library(ggpubr)
library(scales)

ref <- read_csv("test.csv")

ref1 <- ref %>% 
  gather(s_type,s_all,a1,a2,a3) %>%
  gather(bg_type,bg_all,bg_a1,bg_a2,bg_a3) %>%
  gather(err_type,err_all,err_a1,err_a2,err_a3)

acq <- select(ref1, Al:Mg)

lower <- ref1$bg_all-ref1$err_all
upper <- ref1$bg_all+ref1$err_all

label <- c('a1','a2','a3',
           'a1 bg','a2 bg','a3 bg')


for (ii in seq_along(colnames(acq))) {

  current_col <- colnames(acq)[ii]

  print(paste0('Plot col: ', current_col))

  ## plot ##
  g <- ggplot(ref1, aes_string(x=acq[[current_col]], y='s_all',
                               colour='s_type', group='s_type', shape='s_type'),
              pseudo_log_trans(), ylim=c(0,1.5))+
    geom_point(na.rm= FALSE)+ 
    geom_smooth(aes_string(x=acq[[current_col]], y='s_all', colour='s_type'),
                method='lm', formula= y ~ x, show.legend = FALSE, se=FALSE) +
    stat_cor(method = "pearson", label.x = 3,show.legend = FALSE) +
    #    geom_point(aes_string(x=acq[[current_col]], y='bg_all',colour='bg_type',shape='bg_type'),
    #              na.rm = FALSE)+
    #  geom_errorbar(mapping=aes(ymin=lower,ymax=upper), show.legend = FALSE) +
    scale_color_manual("", values = c('royalblue', 'seagreen','tomato',
                                      'royalblue', 'seagreen','tomato'),
                       labels= label) +
    scale_shape_manual("", values=c(16,16,16,
                                    0,0,0),labels= label) + 
    scale_size_manual("", values = c(3,3,3,
                                     3,3,3)) +
    labs(y="a", x=paste(current_col,"(g)")) +
    theme(axis.text.x  = element_text( size = 12), 
          axis.text.y  = element_text(size = 12), 
          axis.title.y = element_text(size = 15),
          axis.title.x = element_text(size = 15)) 

  ggsave(g,file=paste0("plot_",current_col,".pdf"))
  print(g)
  #dev.off()
}

Thank you.

Yria
  • 23
  • 6
  • I am not sure on what basis you want to have changeable x limit. If you have predefined limits, can have a data frame, xlim with column names "Al", "Co", "Mg", and include xlim=xlim$ii in ggplot. – Mohanasundaram Apr 24 '20 at 07:39
  • @Mohanasundaram I want the xlim to automatically extract the limit from the data, since my real data has 38 columns, each having an unique set of xlim variables. The only things that actually compelled the xlim to change were the functions mentioned in this post: https://stackoverflow.com/questions/59270544/change-the-y-axis-limits-in-a-ggplot-of-multiple-plots but I don't know how to manipulate it to my needs. – Yria Apr 24 '20 at 07:55
  • Try adding xlim=c(min(acq[[current_col]], na.rm = TRUE),max(acq[[current_col]], na.rm = TRUE)) – Mohanasundaram Apr 24 '20 at 08:27
  • @Mohanasundaram Sorry, it didn't change anything. – Yria Apr 24 '20 at 08:35
  • For ggplot, we need to have +xlim(). However, the problem is that there are some outliers of in the second columm which make the minimum x value 0.005. – Mohanasundaram Apr 24 '20 at 10:25
  • @Mohanasundaram I know. The 0.005 value is not even recalled in the plot because it belongs to the background values which are comments out. – Yria Apr 24 '20 at 10:50

1 Answers1

1

This will do. I have added the codes for subset and xlim into your original code.

for (ii in seq_along(colnames(acq))) {
  ref2 <- ref1[complete.cases(ref1$s_all),]

  current_col <- colnames(acq)[ii]

  print(paste0('Plot col: ', current_col))

  ## plot ##
  g <- ggplot(ref1, aes_string(x=acq[[current_col]], y='s_all',
                               colour='s_type', group='s_type', shape='s_type'),
              pseudo_log_trans())+
    ylim(c(0,1.5))+ 
    xlim(min(ref2[[current_col]], na.rm = TRUE), max(ref2[[current_col]], na.rm = FALSE)) +
    geom_point(na.rm= FALSE)+ 
    geom_smooth(aes_string(x=acq[[current_col]], y='s_all', colour='s_type'),
                method='lm', formula= y ~ x, show.legend = FALSE, se=FALSE) +
    stat_cor(method = "pearson", show.legend = FALSE) +
    #    geom_point(aes_string(x=acq[[current_col]], y='bg_all',colour='bg_type',shape='bg_type'),
    #              na.rm = FALSE)+
    #  geom_errorbar(mapping=aes(ymin=lower,ymax=upper), show.legend = FALSE) +
    scale_color_manual("", values = c('royalblue', 'seagreen','tomato',
                                      'royalblue', 'seagreen','tomato'),
                       labels= label) +
    scale_shape_manual("", values=c(16,16,16,
                                    0,0,0),labels= label) + 
    scale_size_manual("", values = c(3,3,3,
                                     3,3,3)) +
    labs(y="a", x=paste(current_col,"(g)")) +
    theme(axis.text.x  = element_text( size = 12), 
          axis.text.y  = element_text(size = 12), 
          axis.title.y = element_text(size = 15),
          axis.title.x = element_text(size = 15)) 

  ggsave(g,file=paste0("plot_",current_col,".pdf"))
  print(g)
  #dev.off()
  }

enter image description here enter image description here enter image description here

Mohanasundaram
  • 2,889
  • 1
  • 8
  • 18