Search code examples
rggplot2lineloess

Making lines of best fits in R for multiple lines using ggplot2


I have a titration curve with a line of code

ggplot(Titration.Aug.9, aes(x = Dilution, y = `X..bound`)) +
  geom_line(aes(color = Sample)) +
  geom_point() +
  geom_smooth(formula = y ~ x, method = "loess", se = FALSE, linetype = "dashed") +
  scale_x_continuous(trans = "log10", 
                     breaks = trans_breaks("log10", function(x) 10^x), 
                     labels = trans_format("log10", math_format(10^.x)), 
                     minor_breaks = 10^(seq(0, 7, by = 0.25))) +
  scale_color_brewer(type = "Sample", palette = "Set1") +
  labs(x = "Antibody Dilution", y = "% Cell Binding") +
  theme_minimal()

and I have generated a plot that looks pretty nice. However, I need the data to have a line of best fit for each individual plot point. I tried to do this with loess but I need each line to be a different color. graph image This is the graph I had but I need the lines to be the best fit for each sample not linked by the actual dot plots graph image 2 kind of like this one generated with this line of code

ggplot(Titration.Aug.9, aes(x = Dilution, y = `X..bound`)) +geom_line(aes(color = Sample)) +geom_point() +geom_smooth(formula = y ~ x, method = "loess", se = FALSE,aes(Color=Sample)) +scale_x_continuous(trans = "log10",breaks = trans_breaks("log10", function(x) 10^x),labels = trans_format("log10", math_format(10^.x)),minor_breaks = 10^(seq(0, 7, by = 0.25))) +scale_color_brewer(type="Sample",palette="Set1") +labs(x="Antibody Dilution",y="% Cell Binding") +theme_minimal()

However I need each off these to be colored to each different sample like in the first image but with the line fitting format in the second image. My data is :

dput(Titration.Aug.9)
structure(list(Dilution = c(300L, 900L, 2700L, 8100L, 24300L, 
72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 
300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 
2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 
24300L, 72900L, 218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 
218700L, 300L, 900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 
900L, 2700L, 8100L, 24300L, 72900L, 218700L, 300L, 900L, 2700L, 
8100L, 24300L, 72900L, 218700L), X..bound = c(52.74, 40.31, 30.63, 
18.89, 7.57, 0.8, 0.01, 20.23, 11.29, 7.55, 3.24, 0.54, 0.12, 
0.03, 53.27, 46.82, 38.17, 26.77, 11.59, 2.23, 0.07, 69.25, 63.55, 
56.34, 40.95, 19.35, 2.4, 0.05, 75.8, 68.21, 62.82, 40.33, 11.73, 
0.82, 0.04, 85.75, 82.82, 74.29, 46.63, 9.36, 0.24, 0.05, 71.65, 
66.54, 56.63, 33.96, 6.33, 0.19, 0.03, 85.43, 86.49, 75.73, 51.62, 
15.16, 1.05, 0.01, 92.44, 90.13, 85.92, 72.06, 30.08, 3.15, 0.12
), Sample = c("1mer 0DA", "1mer 0DA", "1mer 0DA", "1mer 0DA", 
"1mer 0DA", "1mer 0DA", "1mer 0DA", "1mer 2DA", "1mer 2DA", "1mer 2DA", 
"1mer 2DA", "1mer 2DA", "1mer 2DA", "1mer 2DA", "1mer 3DA", "1mer 3DA", 
"1mer 3DA", "1mer 3DA", "1mer 3DA", "1mer 3DA", "1mer 3DA", "1mer 4DA", 
"1mer 4DA", "1mer 4DA", "1mer 4DA", "1mer 4DA", "1mer 4DA", "1mer 4DA", 
"5mer 0DA", "5mer 0DA", "5mer 0DA", "5mer 0DA", "5mer 0DA", "5mer 0DA", 
"5mer 0DA", "5mer 2DA", "5mer 2DA", "5mer 2DA", "5mer 2DA", "5mer 2DA", 
"5mer 2DA", "5mer 2DA", "5mer 4DA", "5mer 4DA", "5mer 4DA", "5mer 4DA", 
"5mer 4DA", "5mer 4DA", "5mer 4DA", "5mer 2DA GDG", "5mer 2DA GDG", 
"5mer 2DA GDG", "5mer 2DA GDG", "5mer 2DA GDG", "5mer 2DA GDG", 
"5mer 2DA GDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG", 
"5mer 2DA GDGDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG", "5mer 2DA GDGDG"
)), class = "data.frame", row.names = c(NA, -63L))

Any help is appreciated!! Thank you in advance for your time!! :)


Solution

  • You simply need to map Sample to the color aesthetic inside geom_smooth. I have removed the original geom_line to make the result clearer, but this could be added back in.

    ggplot(Titration.Aug.9, aes(x = Dilution, y = `X..bound`)) +
      geom_point() +
      geom_smooth(formula = y ~ x, method = "loess", se = FALSE,
                  linetype="dashed", aes(color = Sample)) +
      scale_x_continuous(trans = "log10",
                         breaks = trans_breaks("log10", function(x) 10^x),
                         labels = trans_format("log10", math_format(10^.x)),
                         minor_breaks = 10^(seq(0, 7, by = 0.25))) +
      scale_color_brewer(type="Sample",palette="Set1") +
      labs(x="Antibody Dilution",y="% Cell Binding") +
      theme_minimal() 
    

    enter image description here