开发者

plot line over last part of barplot

开发者 https://www.devze.com 2022-12-20 13:33 出处:网络
I have a barplot for which the second half should fit this formula: y~axexp(-b*x^2). Now I want to plot the entire barplot and display the fitted model over the last part of the barplot as it only hol

I have a barplot for which the second half should fit this formula: y~axexp(-b*x^2). Now I want to plot the entire barplot and display the fitted model over the last part of the barplot as it only holds for that part. However, I cannot find a way to display the line-graph only over the second half. If I just do something like


submitted=c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 3L, 2L, 1L, 1L, 4L, 
3L, 2L, 11L, 6L, 2L, 16L, 7L, 17L, 36L, 27L, 39L, 41L, 33L, 42L, 
66L, 92L, 138L, 189L, 249L, 665L, 224L, 309L, 247L, 641L, 777L, 
671L, 532L, 749L, 506L, 315L, 292L, 281L, 130L, 137L, 91L, 40L, 
27L, 34L, 19L, 1L)
x=seq(0:(length(submitted)-1))
y1=rs$submitted[30:(length(submitted)-1)]
x1=seq(0:(length(y1)-1))
fit1=nls(y1~a*x1*exp(-b*x1^2),start=list(a=500,b=.01),trace=TRUE)
barplot(submitted,names.arg=x, las=2, cex.axis=0.8, cex=0.8)
lines(predict(fit1))

The line is displayed, but in the wrong position. So how can I control where the li开发者_StackOverflow中文版ne is drawn?


A reproducible example would have been helpful, but probably the issue is that the bars are not located at the x-coordinates that you expect. You can find out the x-coordinates of the bars by capturing the output of the barplot function:

dat <- 1:5                   # fake data for barplot
fit <- dat+rnorm(5, sd=0.1)  # fake fitted values

bp <- barplot(dat)           # draw plot and capture x-coordinates
lines(bp, fit)               # add line

Edit:
The same principle can be used for adding a partial line. Rewriting your code a bit to get an index idx showing the parts of the data that you want to model:

x <- 0:(length(submitted)-1) 
idx <- 30:(length(submitted)-1)  # the part of the data to be modeled
y1 <- submitted[idx] 
x1 <- idx-30 
fit1 <- nls(y1~a*x1*exp(-b*x1^2),start=list(a=500,b=.01),trace=TRUE) 
# capture the midpoints from the barplot
bp <- barplot(submitted,names.arg=x, las=2, cex.axis=0.8, cex=0.8) 
# subset the midpoints to the range of the fit
lines(bp[idx], predict(fit1)) 

(note that I also changed seq(0:n) to 0:n, because the first does not give you a sequence of 0 to n.)


Take the answer from Aniko and reshape it to your specific problem. I used the data submitted as you have posted.

Define your variables:

y1 <- submitted[30:(length(submitted)-1)]
x1 <- seq(length(y1))

It is enough just using the seq() function this way. It already does the job for you. Then you do the fit and capture the x-values of your barplot() as mentioned by Aniko. That will save the x-values in a matrix so I use as.vector() afterwards to turn it into a vector and make things a little easier.

fit1 <- nls(y1~a*x1*exp(-b*x1^2),start=list(a=500,b=.01),trace=TRUE)
bar <- barplot(submitted, las=2, cex.axis=0.8, cex=0.8)
bar2 <- as.vector(bar)

If you simply print your bar2 you will see the exact values and now you can specify where to place your fit in the plot. Be sure that in your following lines() function the x-vector is of the same length as the y-vector. Eg you can simply do some additional checks with the length() function. Here is the your fit placed into the second half of your barplot:

lines(x = bar2[30:(length(bar2)-1)], y = predict(fit1))
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号