This code generates stimuli for a conjunctive category structure with category A in one category, category B1, B2, B3 in another category
library(MASS)
library(grt)
##
## Attaching package: 'grt'
## The following object is masked from 'package:base':
##
## scale
library(plotrix)
library(data.table)
echo=FALSE
options(digits=10)
Num<-85
#indicate here whether to put a circle around the lines
Circle=0 #1 for draw circle 0 for don't
Sig<-matrix(c(900,50,150,900),2,2)#variance covariance matrix
#first column is length, second is orientation
Mu<-matrix(c(100, 100, 200, 200, 200, 100, 100, 200), 4, 2)#Le Pelley et al (2019) parameters, see their supplementary materials
#sample from multivariate normal distribution and generate stimulus lable
CatA<-mvrnorm(Num*3,Mu[1,],Sig)
stim_file<-paste("CR_A_", 1: (Num*3), sep = "")
A<-cbind(stim_file, CatA)
CatB1<-mvrnorm(Num,Mu[2,],Sig)
stim_file<-paste("CR_B1_", 1: Num, sep = "")
B1<-cbind(stim_file, CatB1)
CatB2<-mvrnorm(Num,Mu[3,],Sig)
stim_file<-paste("CR_B2_", 1: Num, sep = "")
B2<-cbind(stim_file, CatB2)
CatB3<-mvrnorm(Num,Mu[4,],Sig)
stim_file<-paste("CR_B3_", 1: Num, sep = "")
B3<-cbind(stim_file, CatB3)
par(pty="s")
plot(CatA[,1], CatA[,2], pch=21,cex=2,col="navy blue",xlim=c(0, 300),
ylim=c(0, 300),ylab='Angle (degrees)', xlab='Length (pixels)',
main='Conjunctive Rule',frame.plot=FALSE)
points(CatB1[,1], CatB1[,2], pch=24,cex=2,col="red")
points(CatB2[,1], CatB2[,2], pch=24, cex=2,col="red")
points(CatB3[,1], CatB3[,2], pch=24, cex=2,col="red")
lines(2+c(0,1,1,0,0),3+c(0,0,1,1,0))
This figure shows the category space and their decision boundaries
#this transforms orientation into degrees and by pi/500
CatAchange<-CatA[,2]*pi/500*180/pi
CatB1change<-CatB1[,2]*pi/500*180/pi
CatB2change<-CatB2[,2]*pi/500*180/pi
CatB3change<-CatB3[,2]*pi/500*180/pi
#this finds the actual coordinates of each line based on angle and length
#transforming orientation back to radians because that is what r uses for sin, cos
#divide by 2 so that the line will be centred on 0,0
CatAx<-(CatA[,1]*cos(CatAchange*pi/180))/2
CatAy<-(CatA[,1]*sin(CatAchange*pi/180))/2
CatB1x<-(CatB1[,1]*cos(CatB1change*pi/180))/2
CatB1y<-(CatB1[,1]*sin(CatB1change*pi/180))/2
CatB2x<-(CatB2[,1]*cos(CatB2change*pi/180))/2
CatB2y<-(CatB2[,1]*sin(CatB2change*pi/180))/2
CatB3x<-(CatB3[,1]*cos(CatB3change*pi/180))/2
CatB3y<-(CatB3[,1]*sin(CatB3change*pi/180))/2
#the next 4 lines of code create matrices for plot generating
CatA<-cbind(CatA, CatAchange, CatAx, CatAy, -CatAx, -CatAy)
CatB1<-cbind(CatB1, CatB1change, CatB1x, CatB1y, -CatB1x, -CatB1y)
CatB2<-cbind(CatB2, CatB2change, CatB2x, CatB2y, -CatB2x, -CatB2y)
CatB3<-cbind(CatB3, CatB3change, CatB3x, CatB3y, -CatB3x, -CatB3y)
#create df that contains all stimuli detail, then export to csv
CatA_all<-cbind(A, CatAchange, CatAx, CatAy, -CatAx, -CatAy)
CatB1_all<-cbind(B1, CatB1change, CatB1x, CatB1y, -CatB1x, -CatB1y)
CatB2_all<-cbind(B2, CatB2change, CatB2x, CatB2y, -CatB2x, -CatB2y)
CatB3_all<-cbind(B3, CatB3change, CatB3x, CatB3y, -CatB3x, -CatB3y)
#bind all matrices.
bind <-list(CatA_all, CatB1_all, CatB2_all, CatB3_all)
CR_stim<-rbindlist(lapply(bind,as.data.frame), use.names = FALSE) #bind by location, not col name
colnames(CR_stim)<-c("stim_file","length", "ori", "ori_transform", "x_coord", "y_coord", "-x_coord", "-y_coord")
CR_stim<-as.data.frame(CR_stim)
CR_stim[,2:8]<-apply(CR_stim[,2:8], 2,
function(x) as.numeric(as.character(x)))
#write.csv(CR_stim, "CR_stim.csv")
#for lines of length and orientation
# Category A needs to have 3 times the stimuli of other quadrant to keep both category stimuli equivalent
# for (counter in 1:(Num*3))
# {
# png(filename =paste("CR_A_",counter,".png",sep=""), width=412, height=458)#these dimensions give a 300x300pixel plot so line length is in pixels
# #filename =paste("A.CR",counter,".jpg",sep="")
# #quartz(type="jpeg",file=filename)
# plot(CatA[counter,4], CatA[counter,5], type="n", xlab='',ylab='',axes = FALSE,frame.plot=FALSE, xlim=c(-150, 150), ylim=c(-150,150))
# segments(CatA[counter,4], CatA[counter,5], CatA[counter,6], CatA[counter,7], lwd=15, col="blue")
# #for circle around line use this code
# if (Circle==1){draw.circle(0,0,CatA[counter,1]/2,lwd=2)}
#
# dev.off()
# }
#
#
#
# for (counter in 1:Num)
#
# {
# png(filename =paste("CR_B1_",counter,".png",sep=""), width=412, height=458)
# plot(CatB1[counter,4], CatB1[counter,5], type="n", xlab='',ylab='',axes = FALSE,frame.plot=FALSE, xlim=c(-150, 150), ylim=c(-150,150))
# segments(CatB1[counter,4], CatB1[counter,5], CatB1[counter,6], CatB1[counter,7], lwd=15, col="blue")
# #for circle around line use this code
# if (Circle==1){draw.circle(0,0,CatB1[counter,1]/2, lwd=2)}
# dev.off()
# }
#
#
# for (counter in 1:Num)
#
# {
# png(filename =paste("CR_B2_",counter,".png",sep=""), width=412, height=458)
# plot(CatC[counter,4], CatC[counter,5], type="n", xlab='',ylab='',axes = FALSE,frame.plot=FALSE, xlim=c(-150, 150), ylim=c(-150,150))
# segments(CatC[counter,4], CatC[counter,5], CatC[counter,6], CatC[counter,7], lwd=15, col="blue")
# #for circle around line use this code
# if (Circle==1){draw.circle(0,0,CatC[counter,1]/2, lwd=2)}
# dev.off()
# }
#
#
#
# for (counter in 1:Num)
#
# {
# png(filename =paste("CR_B3_",counter,".png",sep=""), width=412, height=458)
# plot(CatD[counter,4], CatD[counter,5], type="n", xlab='',ylab='',axes = FALSE,frame.plot=FALSE, xlim=c(-150, 150), ylim=c(-150,150))
# segments(CatD[counter,4], CatD[counter,5], CatD[counter,6], CatD[counter,7], lwd=15, col="blue")
# #for circle around line use this code
# if (Circle==1){draw.circle(0,0,CatD[counter,1]/2, lwd=2)}
# dev.off()
# }