Drawing a Tangent to the Plot and Finding the X-Intercept using R
Here's an option using derivatives of a fitted spline function (smooth.spline
- you may need to adjust the parameter spar
to your case):
x <- seq(0,40)
y <- dnorm(seq(0,40), mean=25, sd=5)
plot(x, y)
spl <- smooth.spline(y ~ x)
lines(spl, col=2)
newx <- 20
pred0 <- predict(spl, x=newx, deriv=0)
pred1 <- predict(spl, x=newx, deriv=1)
yint <- pred0$y - (pred1$y*newx)
xint <- -yint/pred1$y
xint
The results visually:
plot(x, y)
abline(h=0, col=8)
lines(spl, col=2) # spline
points(pred0, col=2, pch=19) # point to predict tangent
lines(x, yint + pred1$y*x, col=3) # tangent (1st deriv. of spline at newx)
points(xint, 0, col=3, pch=19) # x intercept
Update
Here is an example using your dataset (df
):
# fit smooth spline
plot(y ~ x, df)
spl <- smooth.spline(df$x, df$y, spar=0.3)
newx <- seq(min(df$x), max(df$x), 0.1)
pred <- predict(spl, x=newx, deriv=0)
lines(pred, col=2)
# solve for tangent at a given x
newx <- 25
pred0 <- predict(spl, x=newx, deriv=0)
pred1 <- predict(spl, x=newx, deriv=1)
yint <- pred0$y - (pred1$y*newx)
xint <- -yint/pred1$y
xint
# plot results
plot(y ~ x, df)
abline(h=0, col=8)
lines(spl, col=2) # spline
points(pred0, col=2, pch=19) # point to predict tangent
lines(x, yint + pred1$y*x, col=3) # tangent (1st deriv. of spline at newx)
points(xint, 0, col=3, pch=19) # x intercept
I'm not sure how much noise is in your data, but by using a smaller spar
setting in smooth.spline
, you can increase the detail of the fitted function.
How can I plot a tangent line in R?
The key here is first to calculate the slope and the intercept correctly, and then use geom_ribbon
and geom_abline
. So if you wish to calculate the slope in 0.1, I suggest you calculate the ratio between the y increment and x increment in the interval x = 0.9 and x = 0.11, that is:
xincrement <- 0.02
yincrement <- prc_yld[10, 2] - prc_yld[8, 2]
slope <- yincrement/xincrement
Then, the intercept is:
intercept <- 100-slope*0.1
With these values, we can calculate the y
values of the tangent line:
yvalues <- slope*prc_yld$prc_yld + intercept
Now, let's combine all together:
prc_yld <- as.data.frame(cbind(prc_yld, yvalues))
Now, the plot:
ggplot(prc_yld, aes(x=prc_yld, y = price)) +
geom_ribbon(data = prc_yld, aes(x = prc_yld, ymax = price, ymin = yvalues), fill = "green") +
geom_line(color = "red", size = 1) +
labs(title ="Price/YTM Relationship",x="Yield", y= "Value") +
geom_abline(slope = slope, intercept = intercept, color = "blue", size = 1)
How to totally remove x-axis (and y-axis) from the plot and also draw tangent lines at certain points using Python or R-programming?
Using Python,
import numpy as np
import matplotlib.pyplot as plt
tau = np.arange(-5, 5, 0.01)
a = 0.4
sigma = a*tau
x = 1/a*np.cosh(sigma)
y = 1/a*np.sinh(sigma)
fig, ax = plt.subplots()
ax.plot(x, y, c='black')
# approximate the curve by a cubic
dxds = np.poly1d(np.polyfit(sigma, x, 3)).deriv()
dyds = np.poly1d(np.polyfit(sigma, y, 3)).deriv()
xs, ys, dxs, dys = [], [], [], []
for s in np.linspace(-1, 1, 5):
# evaluate the derivative at s
dx = np.polyval(dxds, s)
dy = np.polyval(dyds, s)
# record the x, y location and dx, dy tangent vector associated with s
xi = 1/a*np.cosh(s)
yi = 1/a*np.sinh(s)
xs.append(xi)
ys.append(yi)
dxs.append(dx)
dys.append(dy)
if s == 0:
ax.text(xi-0.75, yi+1.5, '$u$', transform=ax.transData)
ax.annotate('$a^{-1}$',
xy=(xi, yi), xycoords='data',
xytext=(25, -5), textcoords='offset points',
verticalalignment='top', horizontalalignment='left',
arrowprops=dict(arrowstyle='-', shrinkB=7))
ax.quiver(xs, ys, dxs, dys, scale=1.8, color='black', scale_units='xy', angles='xy',
width=0.01)
ax.plot(xs, ys, 'ko')
# http://stackoverflow.com/a/13430772/190597 (lucasg)
ax.set_xlim(-0.1, x.max())
left, right = ax.get_xlim()
low, high = ax.get_ylim()
ax.arrow(0, 0, right, 0, length_includes_head=True, head_width=0.15 )
ax.arrow(0, low, 0, high-low, length_includes_head=True, head_width=0.15 )
ax.text(0.03, 1, '$t$', transform=ax.transAxes)
ax.text(1, 0.47, '$x$', transform=ax.transAxes)
plt.axis('off')
ax.set_aspect('equal')
plt.show()
yields
How do you draw a straight line tangent to smoothed curve in R?
I tried running your data and d wasn't defined in the code so was not able to reproduce your example.
Using geom_abline you can add a line with the own intercept and slope if you know these dimensions.
ggplot(aes(x = wt, y = mpg), data = mtcars) +
geom_point()+
labs(x = 'wt', y = 'mpg') +
geom_abline(intercept = 10, slope = 6)+
geom_smooth(method = 'loess', col='black', level=0.5, alpha=0.1)
This gave something like this. line with geom_smooth.
I'm not a complete expert but I hope this helps in some way shape or form.
How to add the x intercept from geom_vline in density plot as a label?
One approach is to pre-calc the means and use those to feed geom_vline
and geom_text
:
library(dplyr)
iris_means <- iris %>%
group_by(Species) %>%
summarize(mean = mean(Sepal.Length))
ggplot(iris, aes(Sepal.Length)) +
geom_density() +
geom_vline(data = iris_means, aes(xintercept = mean)) +
geom_text(data = iris_means, aes(x = mean, label = mean),
y = 0.1, angle = 90, vjust = -0.2) +
facet_wrap(~Species)
Finding x-value for a given y-value
You can use unitroot
to find the point where y
matches:
x <- seq(0,40)
y <- pnorm(seq(0,40), mean=25, sd=5)
spl <- smooth.spline(y ~ x)
newy <- 0.85
newx <- uniroot(function(x) predict(spl, x, deriv = 0)$y - newy,
interval = c(0, 40))$root
plot(x, y)
lines(spl, col=2)
points(newx, newy, col=3, pch=19)
Concerning the algorithm, we get from ?uniroot
:
uniroot() uses Fortran subroutine ‘"zeroin"’ (from Netlib) based on
algorithms given in the reference below. They assume a continuous
function (which then is known to have at least one root in the
interval).[...]
Based on ‘zeroin.c’ in http://www.netlib.org/c/brent.shar.
[...]
Brent, R. (1973) Algorithms for Minimization without Derivatives.
Englewood Cliffs, NJ: Prentice-Hall.
See also https://en.wikipedia.org/wiki/Brent%27s_method.
Related Topics
Rbindlist Two Data.Tables Where One Has Factor and Other Has Character Type for a Column
Linear Model with 'Lm': How to Get Prediction Variance of Sum of Predicted Values
Fill in Na Based on the Last Non-Na Value for Each Group in R
Flatten Nested List into 1-Deep List
Findassocs for Multiple Terms in R
Str_Replace (Package Stringr) Cannot Replace Brackets in R
Calculate Average Over Multiple Data Frames
Dual Y Axis (Second Axis) Use in Ggplot2
Ggplot2: Change Factor Order in Legend
Can You Pass a Vector to a Vararg: Vector to Sprintf
How to Apply a Gradient Fill to a Geom_Rect Object in Ggplot2
R 3.5 Is Not Available for Linux
Loop for Reverse Geocoding in R
R Ggplot2 Boxplots - Ggpubr Stat_Compare_Means Not Working Properly
How to Optimize the Following Code with Nested While-Loop? Multicore an Option