0

I want to replace the points in my graph with a line like in the first picture, the second picture is what I have.

but its not quite what im looking for, I want a smooth line without the points

I think I have to use predict for the 1/x curve but I am not sure how, 

noname
  • 13
  • 2
  • 1
    Please try to make this question more reproducible by adding or generating sample data. C.f., https://stackoverflow.com/q/5963269, [mcve], and https://stackoverflow.com/tags/r/info – r2evans Dec 23 '22 at 00:36
  • 1
    A specific request to add to the good comment of @r2evans. Please type `dput(AM_leafP)` and `dput(AM_cost_resorb)` and paste the results into your question. – G5W Dec 23 '22 at 00:43
  • I apologize @G5W and r2evans, I pasted the dput into my questions – noname Dec 23 '22 at 01:02

2 Answers2

0

For smoothing, you can fit a linear model as foolws:

m <- lm(AM_cost_resorb~I(1/AM_leafP), data=data)

Then extract the predictied values on a new data set that covers the range of the exposure variable.

newx <- seq(min(data$AM_leafP), max(data$AM_leafP), by=0.01)
pr <- predict(m, newdata=data.frame(AM_leafP=newx))

And visualize:

plot(AM_cost_resorb~AM_leafP, data=data, type="p", pch= 15, col="red",ylab="Cost of reabsorbtion (kg C m^-2 yr^-1)", xlab="leaf P before senescence (g P/m2)", ylim=c(0,500), las=1)
lines(newx, y=pr, col="blue", lwd=2)

enter image description here


Data:

data <- structure(list(AM_cost_resorb = c(176.01685819061, 21.6704613594849, 
19.007554742708, 50.1865574864131, 17.6174002411188, 40.2758022496774, 
11.0963214407251, 1249.94375253114, 694.894678288085, 339.786950220117, 
42.1452961176151, 220.352895161601, 19.6303352674776, 9.10350287678884, 
10.6222946396451, 44.1984352318898, 21.8069112975004, 42.1237630342764, 
22.7551891190248, 12.9587850506626, 12.0207189111152, 20.2704921282476, 
13.3441156357956, 9.13092569988769, 1781.08346869568, 71.2690023512206, 
80.2376892286713, 344.114362037227, 208.830841645638, 91.1778810401913, 
2220.0120768657, 41.4820962277111, 16.5730025748281, 32.30173229022, 
108.703930214512, 51.6770035143256, 709.071405759588, 87.9618878732223, 
10.4198968123037, 34.4951840238729, 57.8603720445067, 72.3289197551429, 
30.2366643066749, 23.8696161364716, 270.014690419247, 13.8170113452005, 
39.5159584479013, 27.764841260433, 18.0311836472615, 40.5709477295999, 
33.1888820958952, 9.03112843931787, 4.63738971549635, 12.7591169313099, 
4.7998894219979, 8.93458248803248, 7.33904760386628, 12.0940344070925, 
7.17364602165948, 6.514191844409, 9.69911157978057, 6.57874454980745, 
7.90556524435596), AM_leafP = c(0.02840637, 0.230728821, 0.2630533, 
0.099628272, 0.28381032, 0.12414402, 0.45059978, 0.00400018, 
0.00719533500000001, 0.014715103086687, 0.118637201789886, 0.022690875, 
0.254707825, 0.54923913, 0.470708088, 0.113126176837872, 0.22928510745, 
0.118697847481752, 0.219730100850697, 0.38583864, 0.4159485, 
0.24666396693114, 0.374696992776912, 0.547589605297248, 0.00280728, 
0.070156727820596, 0.062314855376136, 0.01453005323695, 0.02394282358199, 
0.0548378613646, 0.00225224, 0.120533928, 0.301695482, 0.15479046, 
0.045996497, 0.096754836, 0.00705147600000001, 0.0568428, 0.47985120103071, 
0.14494777, 0.08641493, 0.069128642, 0.165362156, 0.20947132, 
0.018517511, 0.36187275779699, 0.126531158458224, 0.180083867690804, 
0.277297380904852, 0.1232408972382, 0.15065285976048, 0.55364067, 
1.07819275643191, 0.39187665, 1.04169066418176, 0.55962324, 0.68128731, 
0.41342697, 0.69699564, 0.76755492, 0.515511133042674, 0.760023430328564, 
0.632465844687028)), class = "data.frame", row.names = c(NA, 
-63L))
Edward
  • 10,360
  • 2
  • 11
  • 26
  • How do I remove the points such that only the line remains? – noname Dec 23 '22 at 01:39
  • Replace `type="p"` with `type="n"` in the `plot` command. – Edward Dec 23 '22 at 01:46
  • I was hoping to get a smooth spline line for the curve like in the first picture with the lines, as I was already able to get similar line to yours with this code ``` lines((AM_leafP*1000)[order(AM_leafP*1000)], (AM_cost_resorb[,1])[order(AM_leafP*1000)], pch=16, col="blue") ``` – noname Dec 23 '22 at 02:18
0

Assuming f(1/x) fits the data well. One can use the lm() function to fix the desired function y= a/x + b and then use the predict() function to estimate the desired points.
If a more complicated nonlinear function is required to fit the data then the nls() maybe required

x<- c(176.01685819061, 21.6704613594849, 19.007554742708, 50.1865574864131, 17.6174002411188, 40.2758022496774, 11.0963214407251, 1249.94375253114, 694.894678288085, 339.786950220117, 42.1452961176151, 220.352895161601, 19.6303352674776, 9.10350287678884, 10.6222946396451, 44.1984352318898, 21.8069112975004, 42.1237630342764, 22.7551891190248, 12.9587850506626, 12.0207189111152, 20.2704921282476, 13.3441156357956, 9.13092569988769, 1781.08346869568, 71.2690023512206, 80.2376892286713, 344.114362037227, 208.830841645638, 91.1778810401913, 2220.0120768657, 41.4820962277111, 16.5730025748281, 32.30173229022, 108.703930214512, 51.6770035143256, 709.071405759588, 87.9618878732223, 10.4198968123037, 34.4951840238729, 57.8603720445067, 72.3289197551429, 30.2366643066749, 23.8696161364716, 270.014690419247, 13.8170113452005, 39.5159584479013, 27.764841260433, 18.0311836472615, 40.5709477295999, 33.1888820958952, 9.03112843931787, 4.63738971549635, 12.7591169313099, 4.7998894219979, 8.93458248803248, 7.33904760386628, 12.0940344070925, 7.17364602165948, 6.514191844409, 9.69911157978057, 6.57874454980745, 7.90556524435596)
y<- c(0.02840637, 0.230728821, 0.2630533, 0.099628272, 0.28381032, 0.12414402, 0.45059978, 0.00400018, 0.00719533500000001, 0.014715103086687, 0.118637201789886, 0.022690875, 0.254707825, 0.54923913, 0.470708088, 0.113126176837872, 0.22928510745, 0.118697847481752, 0.219730100850697, 0.38583864, 0.4159485, 0.24666396693114, 0.374696992776912, 0.547589605297248, 0.00280728, 0.070156727820596, 0.062314855376136, 0.01453005323695, 0.02394282358199, 0.0548378613646, 0.00225224, 0.120533928, 0.301695482, 0.15479046, 0.045996497, 0.096754836, 0.00705147600000001, 0.0568428, 0.47985120103071, 0.14494777, 0.08641493, 0.069128642, 0.165362156, 0.20947132, 0.018517511, 0.36187275779699, 0.126531158458224, 0.180083867690804, 0.277297380904852, 0.1232408972382, 0.15065285976048, 0.55364067, 1.07819275643191, 0.39187665, 1.04169066418176, 0.55962324, 0.68128731, 0.41342697, 0.69699564, 0.76755492, 0.515511133042674, 0.760023430328564, 0.632465844687028)


#data frame for prediction
df <- data.frame(x=sort(x))

# fit model y= a/x + b
model <-lm( y ~ I(1/x))
#summary(model)

#plot model
plot(df$x, predict(model, df), type="l", col="blue")
#optional
points(x, y)

enter image description here

Update - response to comments

  1. x is sorted in the data frame, so that points are plotted in order. If not the line could go from x=1 to x=100, back to x=10 etc. thus making a mess. Try removing the sort and see what happens.
  2. The I(1/x) term is to signal lm to perform the inverse transform on x first and then perform the least squares regression.
  3. The predict() function is on the axis since that is the variable used in the plot function. To change this just assign the output from the predict function to a better variable name and plot that. Or use the "ylab= " option.
Dave2e
  • 22,192
  • 18
  • 42
  • 50
  • Thanks, a couple of questions, 1) why did you sort the x values? 2) could you elaborate a bit more on this line of code model <-lm( y ~ I(1/x))? 3)why is your predict() function on the y axis – noname Dec 23 '22 at 05:46
  • @noname See updates above – Dave2e Dec 23 '22 at 13:57