#Let's make up a data
set.seed(1234)
mydat <- data.frame(
    won=as.factor(sample(c(0, 1), 250, replace=TRUE)),  #wining probability
    bid=runif(250, min=0, max=1000) #uniform distribution data
)
head(mydat)
#Let's fit the Logistic Regression using glm function:
mod1 <- glm(won~bid, data=mydat, family=binomial(link="logit"))
summary(mod1)

Call:
glm(formula = won ~ bid, family = binomial(link = "logit"), data = mydat)

Deviance Residuals: 
   Min      1Q  Median      3Q     Max  
-1.202  -1.169  -1.141   1.184   1.214  

Coefficients:
              Estimate Std. Error z value Pr(>|z|)
(Intercept)  0.0582872  0.2629218   0.222    0.825
bid         -0.0001440  0.0004468  -0.322    0.747

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 346.56  on 249  degrees of freedom
Residual deviance: 346.45  on 248  degrees of freedom
AIC: 350.45

Number of Fisher Scoring iterations: 3

A logistic regression model models the relationship between a binary response variable and, in this case, one continuous predictor. The result is a logit-transormed probability as a linear relation to the predictor. The coefficients from mod1 are given in logged odds (which are difficult to interpet), according to: \[logit(p) = \log(\frac{p}{1-p}) = \beta_0 + \beta_1x_1\]

To convert logged odds to probabilities, we can translate the above to: \[p = \frac{\exp(\beta_0 + \beta_1x_1)}{(1+\exp(\beta_0+\beta_1x_1))}\]

Let’s use this information to set up the plot. First, you need a range of the predictor variable:

plotdat <- data.frame(bid=(0:1000))
head(plotdat)

Then using predict, you can obtain predictions based on your model:

preddat <- predict(mod1, newdata=plotdat, se.fit=TRUE)
str(preddat)
List of 3
 $ fit           : Named num [1:1001] 0.0583 0.0581 0.058 0.0579 0.0577 ...
  ..- attr(*, "names")= chr [1:1001] "1" "2" "3" "4" ...
 $ se.fit        : Named num [1:1001] 0.263 0.263 0.262 0.262 0.261 ...
  ..- attr(*, "names")= chr [1:1001] "1" "2" "3" "4" ...
 $ residual.scale: num 1
head(data.frame(preddat))

By specifying se.fit=TRUE, you also get the standard error associated with each fitted value. The resulting data.frame is a matrix with the following components:

In the case of a binomial logit, the value will be 1 (which you can see by entering preddat$residual.scale in R). If you want to see an example of what you’ve calculated so far, you can type head(data.frame(preddat)).

The next step is to set up the plot. We can set up a blank plotting area with the parameters first:

with(mydat, plot(bid, won, type="n", 
    ylim=c(0, 1), ylab="Probability of winning", xlab="Bid"))

Now you can see where it is important to know how to calculate the fitted probabilities. You can draw the line corresponding to the fitted probabilities following the second formula above. Using the preddat data.frame you can convert the fitted values to probabilities and use that to plot a line against the values of your predictor variable.

with(mydat, plot(bid, won, type="n", 
    ylim=c(0, 1), ylab="Probability of winning", xlab="Bid"))
with(preddat, lines(0:1000, exp(fit)/(1+exp(fit)), col="blue"))

Finally, answer the question, the confidence intervals can be added to the plot by calculating the probability for the fitted values +/- 1.96 times the standard error:

with(mydat, plot(bid, won, type="n", 
    ylim=c(0, 1), ylab="Probability of winning", xlab="Bid"))
with(preddat, lines(0:1000, exp(fit)/(1+exp(fit)), col="blue"))
with(preddat, lines(0:1000, exp(fit+1.96*se.fit)/(1+exp(fit+1.96*se.fit)), lty=2))
with(preddat, lines(0:1000, exp(fit-1.96*se.fit)/(1+exp(fit-1.96*se.fit)), lty=2))

LS0tCnRpdGxlOiAiUGxvdHRpbmcgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIHRoZSBwcmVkaWN0ZWQgcHJvYmFiaWxpdGllcyBmcm9tIGEgbG9naXN0aWMgcmVncmVzc2lvbiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCgpgYGB7cn0KI0xldCdzIG1ha2UgdXAgYSBkYXRhCnNldC5zZWVkKDEyMzQpCm15ZGF0IDwtIGRhdGEuZnJhbWUoCiAgICB3b249YXMuZmFjdG9yKHNhbXBsZShjKDAsIDEpLCAyNTAsIHJlcGxhY2U9VFJVRSkpLCAgI3dpbmluZyBwcm9iYWJpbGl0eQogICAgYmlkPXJ1bmlmKDI1MCwgbWluPTAsIG1heD0xMDAwKSAjdW5pZm9ybSBkaXN0cmlidXRpb24gZGF0YQopCmhlYWQobXlkYXQpCgojTGV0J3MgZml0IHRoZSBMb2dpc3RpYyBSZWdyZXNzaW9uIHVzaW5nIGdsbSBmdW5jdGlvbjoKbW9kMSA8LSBnbG0od29ufmJpZCwgZGF0YT1teWRhdCwgZmFtaWx5PWJpbm9taWFsKGxpbms9ImxvZ2l0IikpCnN1bW1hcnkobW9kMSkKCmBgYAoKQSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIG1vZGVscyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYSBiaW5hcnkgcmVzcG9uc2UgdmFyaWFibGUgYW5kLCBpbiB0aGlzIGNhc2UsIG9uZSBjb250aW51b3VzIHByZWRpY3Rvci4gVGhlIHJlc3VsdCBpcyBhIGxvZ2l0LXRyYW5zb3JtZWQgcHJvYmFiaWxpdHkgYXMgYSBsaW5lYXIgcmVsYXRpb24gdG8gdGhlIHByZWRpY3Rvci4gVGhlIGNvZWZmaWNpZW50cyBmcm9tIGBtb2QxYCBhcmUgZ2l2ZW4gaW4gbG9nZ2VkIG9kZHMgKHdoaWNoIGFyZSBkaWZmaWN1bHQgdG8gaW50ZXJwZXQpLCBhY2NvcmRpbmcgdG86CiQkbG9naXQocCkgPSBcbG9nKFxmcmFje3B9ezEtcH0pID0gXGJldGFfMCArIFxiZXRhXzF4XzEkJAoKVG8gY29udmVydCBsb2dnZWQgb2RkcyB0byBwcm9iYWJpbGl0aWVzLCB3ZSBjYW4gdHJhbnNsYXRlIHRoZSBhYm92ZSB0bzoKJCRwID0gXGZyYWN7XGV4cChcYmV0YV8wICsgXGJldGFfMXhfMSl9eygxK1xleHAoXGJldGFfMCtcYmV0YV8xeF8xKSl9JCQKCkxldCdzIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIHNldCB1cCB0aGUgcGxvdC4gRmlyc3QsIHlvdSBuZWVkIGEgcmFuZ2Ugb2YgdGhlIHByZWRpY3RvciB2YXJpYWJsZToKYGBge3J9CnBsb3RkYXQgPC0gZGF0YS5mcmFtZShiaWQ9KDA6MTAwMCkpCmhlYWQocGxvdGRhdCkKYGBgCgpUaGVuIHVzaW5nIGBwcmVkaWN0YCwgeW91IGNhbiBvYnRhaW4gcHJlZGljdGlvbnMgYmFzZWQgb24geW91ciBtb2RlbDoKCmBgYHtyfQpwcmVkZGF0IDwtIHByZWRpY3QobW9kMSwgbmV3ZGF0YT1wbG90ZGF0LCBzZS5maXQ9VFJVRSkKc3RyKHByZWRkYXQpCmhlYWQoZGF0YS5mcmFtZShwcmVkZGF0KSkKYGBgCgoKQnkgc3BlY2lmeWluZyBgc2UuZml0PVRSVUVgLCB5b3UgYWxzbyBnZXQgdGhlICoqc3RhbmRhcmQgZXJyb3IqKiBhc3NvY2lhdGVkIHdpdGggZWFjaCBmaXR0ZWQgdmFsdWUuIFRoZSByZXN1bHRpbmcgYGRhdGEuZnJhbWVgIGlzIGEgbWF0cml4IHdpdGggdGhlIGZvbGxvd2luZyBjb21wb25lbnRzOiAKCiogdGhlIGZpdHRlZCBwcmVkaWN0aW9ucyAoYGZpdGApLCAKKiB0aGUgZXN0aW1hdGVkIHN0YW5kYXJkIGVycm9ycyAoYHNlLmZpdGApLCBhbmQgCiogYSBzY2FsYXIgZ2l2aW5nIHRoZSAqKnNxdWFyZSByb290Kiogb2YgdGhlIGRpc3BlcnNpb24gdXNlZCB0byBjb21wdXRlIHRoZSBzdGFuZGFyZCBlcnJvcnMgKGByZXNpZHVhbC5zY2FsZWApLiAKCkluIHRoZSBjYXNlIG9mIGEgYmlub21pYWwgbG9naXQsIHRoZSB2YWx1ZSB3aWxsIGJlIDEgKHdoaWNoIHlvdSBjYW4gc2VlIGJ5IGVudGVyaW5nIGBwcmVkZGF0JHJlc2lkdWFsLnNjYWxlYCBpbiBgUmApLiBJZiB5b3Ugd2FudCB0byBzZWUgYW4gZXhhbXBsZSBvZiB3aGF0IHlvdSd2ZSBjYWxjdWxhdGVkIHNvIGZhciwgeW91IGNhbiB0eXBlIGBoZWFkKGRhdGEuZnJhbWUocHJlZGRhdCkpYC4KClRoZSBuZXh0IHN0ZXAgaXMgdG8gc2V0IHVwIHRoZSBwbG90LiBXZSBjYW4gc2V0IHVwIGEgYmxhbmsgcGxvdHRpbmcgYXJlYSB3aXRoIHRoZSBwYXJhbWV0ZXJzIGZpcnN0OgoKYGBge3J9CndpdGgobXlkYXQsIHBsb3QoYmlkLCB3b24sIHR5cGU9Im4iLCAKICAgIHlsaW09YygwLCAxKSwgeWxhYj0iUHJvYmFiaWxpdHkgb2Ygd2lubmluZyIsIHhsYWI9IkJpZCIpKQpgYGAKCgpOb3cgeW91IGNhbiBzZWUgd2hlcmUgaXQgaXMgaW1wb3J0YW50IHRvIGtub3cgaG93IHRvIGNhbGN1bGF0ZSB0aGUgZml0dGVkIHByb2JhYmlsaXRpZXMuIFlvdSBjYW4gZHJhdyB0aGUgbGluZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBmaXR0ZWQgcHJvYmFiaWxpdGllcyBmb2xsb3dpbmcgdGhlIHNlY29uZCBmb3JtdWxhIGFib3ZlLiBVc2luZyB0aGUgYHByZWRkYXQgZGF0YS5mcmFtZWAgeW91IGNhbiBjb252ZXJ0IHRoZSBmaXR0ZWQgdmFsdWVzIHRvIHByb2JhYmlsaXRpZXMgYW5kIHVzZSB0aGF0IHRvIHBsb3QgYSBsaW5lIGFnYWluc3QgdGhlIHZhbHVlcyBvZiB5b3VyIHByZWRpY3RvciB2YXJpYWJsZS4KCmBgYHtyfQp3aXRoKG15ZGF0LCBwbG90KGJpZCwgd29uLCB0eXBlPSJuIiwgCiAgICB5bGltPWMoMCwgMSksIHlsYWI9IlByb2JhYmlsaXR5IG9mIHdpbm5pbmciLCB4bGFiPSJCaWQiKSkKd2l0aChwcmVkZGF0LCBsaW5lcygwOjEwMDAsIGV4cChmaXQpLygxK2V4cChmaXQpKSwgY29sPSJibHVlIikpCmBgYAoKRmluYWxseSwgYW5zd2VyIHRoZSBxdWVzdGlvbiwgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGNhbiBiZSBhZGRlZCB0byB0aGUgcGxvdCBieSBjYWxjdWxhdGluZyB0aGUgcHJvYmFiaWxpdHkgZm9yIHRoZSBmaXR0ZWQgdmFsdWVzIGArLy1gIDEuOTYgdGltZXMgdGhlIHN0YW5kYXJkIGVycm9yOgoKYGBge3J9CndpdGgobXlkYXQsIHBsb3QoYmlkLCB3b24sIHR5cGU9Im4iLCAKICAgIHlsaW09YygwLCAxKSwgeWxhYj0iUHJvYmFiaWxpdHkgb2Ygd2lubmluZyIsIHhsYWI9IkJpZCIpKQp3aXRoKHByZWRkYXQsIGxpbmVzKDA6MTAwMCwgZXhwKGZpdCkvKDErZXhwKGZpdCkpLCBjb2w9ImJsdWUiKSkKd2l0aChwcmVkZGF0LCBsaW5lcygwOjEwMDAsIGV4cChmaXQrMS45NipzZS5maXQpLygxK2V4cChmaXQrMS45NipzZS5maXQpKSwgbHR5PTIpKQp3aXRoKHByZWRkYXQsIGxpbmVzKDA6MTAwMCwgZXhwKGZpdC0xLjk2KnNlLmZpdCkvKDErZXhwKGZpdC0xLjk2KnNlLmZpdCkpLCBsdHk9MikpCmBgYAoK