 <p>It sounds like what you're after is to make the fit closer to linear in-between, I think you can force that by interpolating the midpoint as a real point:</p> <pre><code>dat2 = data.frame(x = union(dat$x,dat$x - c(0,diff(dat$x)/2)), y = interp1(dat$x,dat$y,xi = union(dat$x,dat$x - c(0,diff(dat$x)/2)))) </code></pre> <p>(<code>interp1</code> may be unnecessary here, <code>union(dat$y,dat$y - c(0,diff(dat$y)/2))</code> should do the same, but the code above works.)</p> <p>EDIT: Note, in order for <code>diff</code> to work, you need your data to be properly ordered first</p> <p>this creates a new data.frame with points in between the previous ones, if you now spline it, you are weighting a more linear fit</p> <p>EDIT2: You could also use smoothing splines with weights this way, and set the weights of the points in between lower than the weights of the primary points:</p> <pre><code>mod &lt;- splinefun(dat$x, dat$y,method = 'monoH.FC') mod2 &lt;- data.frame(x = seq(0.333, 5, by = 0.1), y = mod(seq(0.333, 5, by = 0.1))) # A set of weights, where each point in-between is weighted half as much dat2$w &lt;- rep(c(0.5,1),ceiling(length(dat2$x)/2))[-1] # Smoothing Spline modelspline &lt;- smooth.spline(dat2$x, dat2$y,dat2$w) # Plot points xplot &lt;- seq(min(dat2$x),max(dat2$x),by = 0.1) # And Plot comparison ggplot() + geom_point(data = dat, aes(x = x, y = y)) + geom_line(data = mod2, aes(x = x, y = y)) + geom_line(data = data.frame(predict(modelspline,xplot)), aes(x = x, y = y),color = 'red') </code></pre>