Tyler Brent de Leon
Tyler Brent de Leon

Reputation: 29

How can I smoothen the curve using R?

Is there any way for me to smoothen this curve [attached below], and not just connecting the points? I've tried using geom_smooth, but it doesn't seem to provide me what I am looking for. I attached my code below.

energy  <- c("Orbital 1 Energy" = "firebrick", "Orbital 2 Energy" = "steelblue")
ggplot(Data, aes(x = BondLength)) +
  geom_line(aes(y = TotalEnergy, color = "Orbital 1 Energy"), size = 1.5) +
  geom_line(aes(y = Orbital2, color = "Orbital 2 Energy"), size = 1.5) +
  
  labs(x = "Bond Length (Angstrom)",
       y = "Energy (Hartree)",
       color = "Legend") +
  scale_color_manual(values = energy)  

Picture: enter image description here
Or is there no other way but to just include many data points to create a smooth curve? Thank you!

Upvotes: 0

Views: 53

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 173793

It sounds as though you are looking for splines. Here's a worked example using something close to your data.

First, we load our libraries then create a new data frame with many sample points on the x axis:

library(splines)
library(ggplot2)

df <- data.frame(BondLength = seq(0.5, 5, 0.01))

Now we create an lm using ns to fit splines, and predict the y values at each x value:

df$TotalEnergy <- predict(lm(TotalEnergy ~ ns(BondLength, df = 8), Data), df)
df$Orbital2 <- predict(lm(Orbital2 ~ ns(BondLength, df = 8), Data), df)

Now we just use your plotting code but use the new data frame instead, and we add the points from the original data frame so that we can see the fit obtained:

ggplot(df, aes(x = BondLength)) +
  geom_line(aes(y = TotalEnergy, color = "Orbital 1 Energy"), size = 1.5) +
  geom_line(aes(y = Orbital2, color = "Orbital 2 Energy"), size = 1.5) +
  geom_point(data = Data, aes(y = TotalEnergy), alpha = 0.5) +
  geom_point(data = Data, aes(y = Orbital2), alpha = 0.5) +
  labs(x = "Bond Length (Angstrom)",
       y = "Energy (Hartree)",
       color = "Legend") +
  scale_color_manual(values = energy) +
  theme(panel.grid = element_blank())


Data used

Data <- data.frame(BondLength = 1:10 / 2,
                   TotalEnergy = c(0.28, -0.18, -0.35, -0.42, -0.45, -0.47,
                                   -0.4875, -0.48, -0.48, -0.48),
                   Orbital2    = c(-0.36, -0.59, -0.56, -0.51, -0.49, -0.485,
                                    -0.482, -0.48, -0.48, -0.48))

energy  <- c("Orbital 1 Energy" = "firebrick", "Orbital 2 Energy" = "steelblue")

Upvotes: 1

Related Questions