0

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!

  • Where is `Data`? – Duck Dec 08 '20 at 17:55
  • 1
    Without being able to fiddle around with the dataset you are working with, I would recommend taking a look at [this question](https://stackoverflow.com/questions/35205795/plotting-smooth-line-through-all-data-points/35206832). Depending on what you want to achieve `stat_smooth()` may work for you. Otherwise, you may want to interpolate your data using [`spline`](https://en.wikipedia.org/wiki/Cubic_Hermite_spline) as Stibu recommended. – Yuka Takemon Dec 08 '20 at 18:25

1 Answers1

1

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")
Allan Cameron
  • 147,086
  • 7
  • 49
  • 87