# # Iso-sensitivity = constant d' (the ROC). The optimal operating point on # that ROC is where slope = beta, i.e. k = d'/2 + log(beta)/d'. # # Usage: # Rscript tools/plot_roc_beta.R d_prime <- 2 betas <- c(10, 0.1) roc_curve <- function(d, n = 400) { far <- ppoints(n) data.frame( d = d, far = far, hr = pnorm(qnorm(far) + d) ) } operating_point <- function(d, beta) { k <- d / 2 + log(beta) / d data.frame( d = d, beta = beta, k = k, far = 1 - pnorm(k), hr = 1 - pnorm(k - d) ) } iso_bias <- function(beta, d_seq = seq(0.35, 4, length.out = 200)) { k <- d_seq / 2 + log(beta) / d_seq data.frame( beta = beta, d = d_seq, far = 1 - pnorm(k), hr = 1 - pnorm(k - d_seq) ) } # Tangent (iso-expected-value) line through the operating point, slope = beta tangent_seg <- function(pt, beta, far_max = 1) { # hr = pt$hr + beta * (far - pt$far) far0 <- max(0, pt$far - pt$hr / beta) far1 <- min(far_max, pt$far + (1 - pt$hr) / beta) data.frame( beta = beta, far = c(far0, far1), hr = pt$hr + beta * (c(far0, far1) - pt$far) ) } rocs <- do.call(rbind, lapply(c(1, d_prime, 3), function(d) { out <- roc_curve(d) out$label <- sprintf("d' = %g", d) out })) pts <- do.call(rbind, lapply(betas, function(b) operating_point(d_prime, b))) pts$label <- sprintf("beta = %s", format(pts$beta, scientific = FALSE, trim = TRUE)) bias <- do.call(rbind, lapply(betas, iso_bias)) bias$label <- sprintf("iso-bias beta = %s", format(bias$beta, scientific = FALSE, trim = TRUE)) tans <- do.call(rbind, lapply(seq_len(nrow(pts)), function(i) { tangent_seg(pts[i, ], pts$beta[i]) })) paper <- "#f0ebe1" teal <- "#2a6f78" rust <- "#c44a24" olive <- "#6a7342" ink <- "#2c2a26" library(ggplot2) p <- ggplot() + geom_abline(slope = 1, intercept = 0, colour = ink, linetype = "dotted", linewidth = 0.4) + geom_line( data = rocs, aes(far, hr, group = label, colour = "iso-sensitivity (ROC)", linetype = label), linewidth = 0.7 ) + geom_line( data = bias, aes(far, hr, group = label, colour = "iso-bias (constant beta)"), linewidth = 0.5, linetype = "longdash" ) + geom_line( data = tans, aes(far, hr, group = beta, colour = "optimal slope = beta"), linewidth = 0.45 ) + geom_point( data = pts, aes(far, hr, colour = "optimal criterion on d' = 2"), size = 2.6 ) + geom_text( data = pts, aes(far, hr, label = label), colour = ink, size = 3.1, hjust = ifelse(pts$beta > 1, -0.12, 1.12), vjust = ifelse(pts$beta > 1, 0.3, -0.4) ) + coord_fixed(xlim = c(0, 1), ylim = c(0, 1), expand = FALSE) + scale_x_continuous("False alarm rate P(Yes | N)", breaks = seq(0, 1, 0.25)) + scale_y_continuous("Hit rate P(Yes | S)", breaks = seq(0, 1, 0.25)) + scale_colour_manual( values = c( "iso-sensitivity (ROC)" = teal, "iso-bias (constant beta)" = olive, "optimal slope = beta" = rust, "optimal criterion on d' = 2" = rust ) ) + scale_linetype_manual(values = c("d' = 1" = "dotted", "d' = 2" = "solid", "d' = 3" = "dotdash")) + labs( title = "ROC iso-sensitivity and optimal criterion for a 10:1 base rate", subtitle = sprintf( "Equal-variance Gaussian. On d' = %g, k* = d'/2 + ln(beta)/d'. beta = 10 (noise 10:1) or 0.1 (signal 10:1).", d_prime ), colour = NULL, linetype = NULL ) + theme_minimal(base_size = 11) + theme( plot.background = element_rect(fill = paper, colour = NA), panel.background = element_rect(fill = paper, colour = NA), panel.grid.minor = element_blank(), panel.grid.major = element_line(colour = "#d9d3c6", linewidth = 0.3), legend.position = "bottom", legend.box = "vertical", plot.title = element_text(face = "bold", colour = ink), plot.subtitle = element_text(colour = ink, size = 9) ) + guides( colour = guide_legend(order = 1, override.aes = list(linetype = c("solid", "longdash", "solid", "blank"), shape = c(NA, NA, NA, 16))), linetype = guide_legend(order = 2) ) print(pts[, c("beta", "k", "far", "hr")]) print(p) source("~/Dropbox/Articles & Presentations/2026/human_ai_handbook/tools/plot_roc_beta.R") print(p) roc_curve <- function(d, n = 500) { far <- ppoints(n) data.frame(d = d, far = far, hr = pnorm(qnorm(far) + d)) } print(p) source("~/Dropbox/Articles & Presentations/2026/human_ai_handbook/tools/plot_roc_beta.R") source("~/Dropbox/Articles & Presentations/2026/human_ai_handbook/tools/plot_roc_beta.R") print(p) x < 3 x <- rnorm(50) * 10 plot(x) x <- x - mean(x) +33 mean(x) plot(x) abline(mean(x),0) text(25,mean(x),paste("The mean is",mean(x))) x <- print("the mean is", 33) x ChickWeight ChickWeight(order(ChickWeight$Time)) data(ChickWeight) ChickWeight(order(ChickWeight$Time)) ChickWeight[order(ChickWeight$Time)] ChickWeight[order(ChickWeight$time)] ChickWeight[order(ChickWeight$time),] ChickWeight$Time order(ChickWeight$Time) ChickWeight[order(ChickWeight$Time),] ChickWeight[order(ChickWeight$Time)] setwd("~/Dropbox/courses/5210-2026/web-5210/psy5210/Projects/Chapter5") colors() colors()[3] colors()[1:20] palette() barplot(rep(1,8)) barplot(rep(1,8),colors=1:8) barplot(rep(1,8),col=1:8) pallete() palette9) palette() barplot(rep(1,8),col=3) barplot(rep(1,8),col="#61D04F") barplot(rep(1,8),col="#61D040") barplot(rep(1,8),col="#61D010") barplot(rep(1,8),col="#33D010") barplot(rep(1,8),col=1:5) barplot(rep(1,16),col=1:16) x <- c(3,2.5,0,12,15, 18, 22,33,26,23,18,17,8,9,5,11) y <- c(14, 8,2,15, 3, 1, 6, 9, 12,11,12,7,8,6,1,5) plot(x,y,type="b",pch=16) colors()[1:10] barplot(rep(1,10,col=colors()[1:10]) ) barplot(rep(1,10),col=colors()[1:10]) par(mfrow=c(1,3)) plot(x,y,type="b",pch=16, col = cm.colors(16),cex=3) text(x,y,1:16,cex=.8,col="black") cm.colors() cm.colors(10) source("~/Dropbox/courses/5210-2026/web-5210/psy5210/Projects/Chapter6/Chapter6Walkthrough.R", echo = TRUE) plot(x,y,type="b",pch=16) x <- c(3,2.5,0,12,15, 18, 22,33,26,23,18,17,8,9,5,11) y <- c(14, 8,2,15, 3, 1, 6, 9, 12,11,12,7,8,6,1,5) plot(x,y,type="b",pch=16) par(mfrow=c(1,3)) plot(x,y,type="b",pch=16, col = cm.colors(16),cex=3) text(x,y,1:16,cex=.8,col="black") plot(x,y,type="b",pch=16, col = terrain.colors(16),cex=3) text(x,y,1:16,cex=.8,col="white") ##Greyscale plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col= rep(c("white","black"),each=8)) ##notice reverse colors #dev.off() grey() grey(1) grey(0) grey(.5) ##Greyscale plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") source("~/Dropbox/courses/5210-2026/web-5210/psy5210/Projects/Chapter6/Chapter6Walkthrough.R", echo = TRUE) plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="white") ##notice reverse colors dev.off() plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="white") ##notice reverse colors plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="white") ##notice reverse colors dev.off() dev.off() source("~/Dropbox/courses/5210-2026/web-5210/psy5210/Projects/Chapter6/Chapter6Walkthrough.R", echo = TRUE) plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="white") ##notice reverse colors x <- c(3,2.5,0,12,15, 18, 22,33,26,23,18,17,8,9,5,11) y <- c(14, 8,2,15, 3, 1, 6, 9, 12,11,12,7,8,6,1,5) plot(x,y,type="b",pch=16) ##there is a start and an end--let's adjust the color: #pdf("c6col4.pdf",width=9,height=4) par(mfrow=c(1,3)) plot(x,y,type="b",pch=16, col = cm.colors(16),cex=3) text(x,y,1:16,cex=.8,col="black") plot(x,y,type="b",pch=16, col = terrain.colors(16),cex=3) text(x,y,1:16,cex=.8,col="white") ##Greyscale plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="white") ##notice reverse colors #text(x,y,1:16,cex=.8,col= rep(c("white","black"),each=8)) ##notice reverse colors #dev.off() dev.off() dev.off() x <- c(3,2.5,0,12,15, 18, 22,33,26,23,18,17,8,9,5,11) y <- c(14, 8,2,15, 3, 1, 6, 9, 12,11,12,7,8,6,1,5) plot(x,y,type="b",pch=16) ##there is a start and an end--let's adjust the color: #pdf("c6col4.pdf",width=9,height=4) par(mfrow=c(1,3)) plot(x,y,type="b",pch=16, col = cm.colors(16),cex=3) text(x,y,1:16,cex=.8,col="black") plot(x,y,type="b",pch=16, col = terrain.colors(16),cex=3) text(x,y,1:16,cex=.8,col="white") ##Greyscale plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="white") ##notice reverse colors #text(x,y,1:16,cex=.8,col= rep(c("white","black"),each=8)) ##notice reverse colors #dev.off() plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="black") ##notice reverse colors source("~/Dropbox/courses/5210-2026/web-5210/psy5210/Projects/Chapter6/Chapter6Walkthrough.R", echo = TRUE) dev.off() dev.off() dev.off() plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="grey") ##notice reverse colors source("~/Dropbox/courses/5210-2026/web-5210/psy5210/Projects/Chapter6/Chapter6Walkthrough.R", echo = TRUE) x <- c(3,2.5,0,12,15, 18, 22,33,26,23,18,17,8,9,5,11) y <- c(14, 8,2,15, 3, 1, 6, 9, 12,11,12,7,8,6,1,5) plot(x,y,type="b",pch=16) ##Greyscale plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="grey") ##notice reverse colors #text(x,y,1:16,cex=.8,col= rep(c("white","black"),each=8)) ##notice reverse colors #dev.off() plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="orange") ##notice reverse colors source("~/Dropbox/courses/5210-2026/web-5210/psy5210/Projects/Chapter6/Chapter6Walkthrough.R", echo = TRUE) dev.off() x <- c(3,2.5,0,12,15, 18, 22,33,26,23,18,17,8,9,5,11) y <- c(14, 8,2,15, 3, 1, 6, 9, 12,11,12,7,8,6,1,5) ##Greyscale plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="red") ##notice reverse colors #text(x,y,1:16,cex=.8,col= rep(c("white","black"),each=8)) ##notice reverse colors #dev.off() dev.off() dev.off() ##Greyscale plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="red") ##notice reverse colors #text(x,y,1:16,cex=.8,col= rep(c("white","black"),each=8)) ##notice reverse colors #dev.off() plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") text(x,y,1:16,cex=.8,col="red") ##notice reverse colors text(x,y,1:16,cex=.8,col= rep(c("white","black"),each=8)) ##notice reverse colors rep(c("white","black"),each=8) rep(c("white","black"),8) rep(c("white","black"),each=8) plot(x,y,type="l",cex=2) points(x,y,type="p",cex=3, col = grey(1:16/16),pch=16) points(x,y,type="p",cex=3,col="black") library(gplots) #pdf("c6col5.pdf",width=9,height=4) plot(1:50,rep(10,50),pch=15,cex=2,xlim=c(-20,50),ylim=c(0,12),col=redgreen(50), xaxt="n",yaxt="n",xlab="",ylab="",bty="n") text(-12,10,"redgreen:") points(1:50,rep(9,50),pch=15,cex=2,col=greenred(50)) text(-12,9,"greenred:") points(1:50,rep(8,50),pch=15,cex=2,col=bluered(50)) text(-12,8,"bluered:") points(1:50,rep(7,50),pch=15,cex=2,col=redblue(50)) text(-12,7,"redblue:") points(1:50,rep(6,50),pch=15,cex=2,col=colorpanel(50,"orange","red")) text(-12,6,"colorpanel: orange red") points(1:50,rep(5,50),pch=15,cex=2,col=colorpanel(50,"black","green")) text(-12,5,"colorpanel: black green") points(1:50,rep(4,50),pch=15,cex=2,col=colorpanel(50,"blue","green")) text(-12,4,"colorpanel: blue green") points(1:50,rep(3,50),pch=15,cex=2,col=colorpanel(50,"pink","red")) text(-12,3,"colorpanel: pink red") points(1:50,rep(2,50),pch=15,cex=2,col=colorpanel(50,"yellow","orange","brown")) text(-12,2,"colorpanel: yel-or-brn") points(1:50,rep(1,50),pch=15,cex=2,col=rich.colors(50)) text(-12,1,"richcolors:") points(1:50,rep(0,50),pch=15,cex=2,col=rich.colors(50,palette="blues")) text(-12,0,"richcolors: blues") #install.packages("RColorBrewer") library(RColorBrewer) display.brewer.all() display.brewer.pal(10,"Blues") display.brewer.pal(6,"Greens") display.brewer.pal(12,"BrBG") display.brewer.pal(7,"Accent") display.brewer.pal(10,"Blues") display.brewer.pal(6,"Greens") display.brewer.pal(12,"BrBG") display.brewer.pal(7,"Accent") palette <- brewer.pal(11,"Spectral") palette(palette) barplot(runif(10),col=1:10,main="Spectral colors") palettex <- brewer.pal(11,"Spectral") palette(palettex) palette() barplot(runif(10),col=1:10,main="Spectral colors") barplot(runif(22),col=brewer.pal(11,"BrBG"),main="Brown-Green palette") x <- rnorm(2500)*3 y <- x + sqrt(rnorm(2500)^2) *8 tab <- table(round(x),round(y)) par(mfrow=c(2,3)) image(tab) round(x) round(y) tab <- table(round(x),round(y)) tab table(round(x)) table(round(x),round(y)) image(tab) image(tab,col=brewer.pal(11,"Oranges")) image(tab,col=brewer.pal(11,"Blues"),legend=T) x <- rnorm(2500)*3 y <- x + sqrt(rnorm(2500)^2) *8 tab <- table(round(x),round(y)) par(mfrow=c(2,3)) image(tab) image(tab,col=brewer.pal(11,"Oranges")) image(tab,col=brewer.pal(11,"Blues"),legend=T) image(tab,col=blue2green(50)) image(tab,col=blue2yellow(50)) barplot(runif(20),col=primary.colors(20)) library("colorRamps") #pdf("c6col9.pdf",width=9,height=5) par(mfrow=c(1,3)) image(tab,col=blue2green(50)) image(tab,col=blue2yellow(50)) barplot(runif(20),col=primary.colors(20)) colorblind <- c(rgb(0,0,0,maxColorValue=255), rgb(230,159,0,maxColorValue=255), rgb(86,180,233,maxColorValue=255), rgb(0,158,115,maxColorValue=255), rgb(240,228,66,maxColorValue=255), rgb(0,114,178,maxColorValue=255), rgb(213,94,0,maxColorValue=255), rgb(204,121,167,maxColorValue=255)) par(mfrow=c(1,2)) colorblind <- c(rgb(0,0,0,maxColorValue=255), rgb(230,159,0,maxColorValue=255), rgb(86,180,233,maxColorValue=255), rgb(0,158,115,maxColorValue=255), rgb(240,228,66,maxColorValue=255), rgb(0,114,178,maxColorValue=255), rgb(213,94,0,maxColorValue=255), rgb(204,121,167,maxColorValue=255)) palette(colorblind) barplot(1:10,col=1:10) barplot(1:10,col=1:10) barplot(1:10,density=10,angle=runif(10)*180,add=T) barplot(1:10,density=10,angle=runif(10)*180,add=T) set.seed(101) dat <- t(matrix(runif(20),5,4) * (1:5)^2) cats =c("Fr","So","Ju","Sr","Gr") #pdf("c6-colorscheme1.pdf",width=9,height=4) par(mfrow=c(1,4)) palette(c("midnightblue","gold","darkgreen","maroon","dodgerblue")) matplot(dat,type="l",lwd=3,lty=1,xaxt="n",ylim=c(1,25)) legend(2,25,rev(cats),lty=1,lwd=3,col=5:1) pie(c(1,13,5,2,1),labels=c("Fr","So","Ju","Sr","Gr"),col=1:5) dotchart(c(1,13,5,2,1),labels=c("Fr","So","Ju","Sr","Gr"),col=1:5,pch=16,pt.cex=3) barplot(c(10,5,8,4,6),names=cats,col=1:5) #dev.off() ##Whoops, somebody didn't like the color scheme. palette( brewer.pal(9,"Set1")) matplot(dat,type="l",lwd=3,lty=1,xaxt="n",ylim=c(1,25)) legend(2,25,rev(cats),lty=1,lwd=3,col=5:1) pie(c(1,13,5,2,1),labels=c("Fr","So","Ju","Sr","Gr"),col=1:5) dotchart(c(1,13,5,2,1),labels=c("Fr","So","Ju","Sr","Gr"),col=1:5,pch=16,pt.cex=3) barplot(c(10,5,8,4,6),names=cats,col=1:5) #dev.off() par(mfrow=c(1,1),mar=c(0,0,0,0)) cols <- c(rgb(240,0,5,maxColorValue=255,alpha=120), rgb(230,225,5,maxColorValue=255,alpha=255), rgb(12,100,250,maxColorValue=255,alpha=120)) ##In a random sample, of women, we might have 40 self-identified feminists, ##and 10 employed in the financial industry plot(0,type="n",xlim=c(0,10),ylim=c(0,10),bty="n",xaxt="n",yaxt="n",xlab="",ylab="") segments(0:10,0,0:10,10,lty=3) segments(0,0:10,10,0:10,lty=3) rect(0,0,10,10,col=cols[3]) rect(0,6,10,7,col=cols[2]) rect(1,1,6,9,col=cols[1]) text(3.5,5,"Feminists (40)") text(3.5,6.5,"Lindas (5)") text(8,6.5,"Bank\nworkers (10)") text(7,.5,"Women (100)") catnames <- c("izzy", "dilly", "spooky", "bernard", "jack") catcolors <- c("black", "orange", "gray", "brown") datavals <- round(exp(runif(20)*5)) ##random 600 numbers with a mean of 76 and a standard deviation of 6.9 data <- data.frame(Cat=rep(catnames,4), Color=rep(catcolors, each=5), Count=datavals ) #pdf("c6balloon1.pdf",width=6,height=6) balloonplot( data$Cat, data$Color, data$Count, colmar=2,ylab="Color",xlab="Cat name") #dev.off() data balloonplot(data$Cat,data$color,data$Count) #pdf("c6balloon1.pdf",width=6,height=6) balloonplot( data$Cat, data$Color, data$Count, colmar=2,ylab="Color",xlab="Cat name") balloonplot(data$Cat,data$color,data$Count) dev.off() dev.off() balloonplot( data$Cat, data$Color, data$Count, colmar=2,ylab="Color",xlab="Cat name") ?balloonplot balloonplot( data$Cat, data$Color, data$Count, colmar=2,ylab="Color",xlab="Cat name",cum.margins=F) bubbleplot( data$Cat, data$Color, data$Count, colmar=2,ylab="Color",xlab="Cat name",cum.margins=F) bubbleplot( data$Cat, data$Color, data$Count, colmar=2,ylab="Color",xlab="Cat name") bubbleplot( data$Cat, data$Color, data$Count, colmar=2,ylab="Color",xlab="Cat name") catch.t <- xtabs(Catch~Year+Age, catch.d) # example table catch.m <- as.matrix(as.data.frame(unclass(catch.t))) # example matrix catch.t catch.m bubbleplot(Catch~Age+Year, data=catch.d) ##Joyplot from plotrix: x1<-c(sample(20:50,20),sample(40:80,30)) x2<-c(sample(10:40,30),sample(50:90,30)) x3<-sample(20:90,50) xdens1<-density(x1) xdens2<-density(x2) xdens3<-density(x3) xlist<-list(first=xdens1,second=xdens2,third=xdens3,fourth=xdens2,fifth=xdens3,sixth=xdens1) joyPlot(xlist,fill=rgb(.2,.2,.2,alpha=.80),newrange=c(0,2.5),border="grey70") ##Anne's example par(mfrow=c(1,6),mar=c(1,5,1,0)) barplot(runif(20),horiz=T,xaxt="n",col="blue",names=LETTERS[1:20],las=1) par(mar=c(1,0,1,0)) barplot(runif(20),horiz=T,xaxt="n",col="salmon") barplot(runif(20),horiz=T,xaxt="n",col="limegreen") barplot(runif(20),horiz=T,xaxt="n",col="orange") barplot(runif(20),horiz=T,xaxt="n",col="purple") barplot(runif(20),horiz=T,xaxt="n",col="orange4")