<jupyter_start><jupyter_text>Computes overall preference for the light source locationGenerates __figures 2-3__, __table 1__, and corresponding statistical comparisons<jupyter_code>rm(list= ls())
library(dplyr)
library(ggplot2)
library(binom)
library(lmerTest)
library(effsize)<jupyter_output><empty_output><jupyter_text>Loading results<jupyter_code>results= read.csv2(file.path('Data', 'results_with_estimates.csv'), sep=';', dec='.', stringsAsFactors=FALSE)
results$Observer <- as.factor(results$Observer)<jupyter_output><empty_output><jupyter_text>Overall summary table on individual observers__Table S1__ in the manuscript<jupyter_code>trials.per.participant <- results %>%
    dplyr::group_by(Observer) %>%
    dplyr::summarize(total.trials= n(),
                     proportion.of.trials.with.an.estimate= 100*sum(Confidence>0)/total.trials,
                     estimate.on.left.CI.lower= 100*binom::binom.exact(sum(sign(true_angle[Confidence>0])==-1), sum(Confidence>0), conf.level = 0.99)$lower,
                     estimate.on.left.mean= 100*mean(sign(true_angle[Confidence>0])==-1),
                     estimate.on.left.CI.upper= 100*binom::binom.exact(sum(sign(true_angle[Confidence>0])==-1), sum(Confidence>0), conf.level = 0.99)$upper,
                     relative.orientation= mean(abs(true_angle[Confidence>0])*180/pi),
                     relative.orientation.sd= sd(abs(true_angle[Confidence>0])*180/pi),
                     confidence.mean= mean(Confidence[Confidence>0]),
                     confidence.sd= sd(Confidence[Confidence>0])
                     )

trials.per.participant<jupyter_output><empty_output><jupyter_text>Plotting distributions of the _raw_ estimates__Figures 1ACE__ in the manuscript.<jupyter_code>est.hist <- hist(results$angle, breaks = seq(-pi, pi, length.out= 59), plot=FALSE)
est.hist.df <- data.frame(angle= est.hist$mids, 
                          proportion= 100*est.hist$counts/sum(est.hist$counts))
                

observers.hist <- data.frame()
for(current.observer in unique(results$Observer)){
    current.hist <- hist(results$angle[results$Observer== current.observer], breaks = seq(-pi, pi, length.out= 59), plot=FALSE)
    
    observers.hist <- rbind(observers.hist,
                            data.frame(angle= current.hist$mids, 
                                       proportion= 100*current.hist$counts/sum(current.hist$counts),
                                       Observer= current.observer))
}

descartes.raw.plot <- ggplot(data= observers.hist, aes(x= angle, y= proportion, color= Observer)) + 
    geom_line()+
    geom_ribbon(data= est.hist.df, aes(ymin= 0, ymax= proportion, color= NA), alpha= 0.5)+
#     coord_polar(start = pi, direction=1) + 
    scale_x_continuous(breaks=seq(-pi, pi, length.out = 9), labels = seq(-180, 180, length.out = 9), lim= c(-pi, pi))+
    xlab('Raw angle [deg]')
print(descartes.raw.plot)
# ggsave(file="Generated figures/Raw angle - descartes.pdf", plot= descartes.raw.plot, width= 12, height= 8, units = 'cm')

polar.raw.plot <- ggplot(data= observers.hist, aes(x= angle, y= proportion, color= Observer)) + 
    geom_line()+
    geom_ribbon(data= est.hist.df, aes(ymin= 0, ymax= proportion, color= NA), alpha= 0.5)+
    coord_polar(start = pi, direction=1) + 
    scale_x_continuous(breaks=seq(-pi, pi, length.out = 9), labels = seq(-180, 180, length.out = 9), lim= c(-pi, pi))+
    xlab('Raw angle [deg]')
print(polar.raw.plot)
# ggsave(file="Generated figures/Raw angle - polar.pdf", plot= polar.raw.plot, width= 12, height= 8, units = 'cm')

# computing proportion to the left of the vertical
est.2.left <- results %>%
    dplyr::filter(Confidence > 0) %>%
    dplyr::mutate(est.2.left= angle<0) %>%
    dplyr::group_by(Observer) %>%
    dplyr::summarize(count= sum(est.2.left),
                     proportion= mean(est.2.left), 
                     ci.lower= binom::binom.exact(count, n(), conf.level = 0.99)$lower,
                     ci.upper= binom::binom.exact(count, n(), conf.level = 0.99)$upper)

est.2.left.raw.plot <- ggplot(data= est.2.left, aes(x= Observer, y= proportion, 
                                                    ymin= ci.lower, ymax= ci.upper, 
                                                    color= Observer)) + 
    geom_errorbar() + 
    geom_point() + 
    scale_x_discrete(limits = rev(levels(results$Observer))) +
    ylim(0, 1)
    
print(est.2.left.raw.plot)
# ggsave(file="Generated figures/Raw angle - estimates proportion.pdf", plot= est.2.left.raw.plot, width= 12, height= 8, units = 'cm')<jupyter_output><empty_output><jupyter_text>Plotting distributions of the _corrected for mirroring_ estimates__Figures 1BDG__ in the manuscript.<jupyter_code>est.hist <- hist(results$true_angle, breaks = seq(-pi, pi, length.out= 59), plot=FALSE)
est.hist.df <- data.frame(angle= est.hist$mids, 
                          proportion= 100*est.hist$counts/sum(est.hist$counts))
                

observers.hist <- data.frame()
for(current.observer in unique(results$Observer)){
    current.hist <- hist(results$true_angle[results$Observer== current.observer], breaks = seq(-pi, pi, length.out= 59), plot=FALSE)
    
    observers.hist <- rbind(observers.hist,
                            data.frame(angle= current.hist$mids, 
                                       proportion= 100*current.hist$counts/sum(current.hist$counts),
                                       Observer= current.observer))
}

descartes.corr.plot <- ggplot(data= observers.hist, aes(x= angle, y= proportion, color= Observer)) + 
    geom_line()+
    geom_ribbon(data= est.hist.df, aes(ymin= 0, ymax= proportion, color= NA), alpha= 0.5)+
#     coord_polar(start = pi, direction=1) + 
    scale_x_continuous(breaks=seq(-pi, pi, length.out = 9), labels = seq(-180, 180, length.out = 9), lim= c(-pi, pi))+
    xlab('Raw angle [deg]')
print(descartes.corr.plot)
# ggsave(file="Generated figures/Corrected angle - descartes.pdf", plot= descartes.corr.plot, width= 12, height= 8, units = 'cm')


polar.corr.plot <- ggplot(data= observers.hist, aes(x= angle, y= proportion, color= Observer)) + 
    geom_line()+
    geom_ribbon(data= est.hist.df, aes(ymin= 0, ymax= proportion, color= NA), alpha= 0.5)+
    coord_polar(start = pi, direction=1) + 
    scale_x_continuous(breaks=seq(-pi, pi, length.out = 9), labels = seq(-180, 180, length.out = 9), lim= c(-pi, pi))+
    xlab('Raw angle [deg]')
print(polar.corr.plot)
# ggsave(file="Generated figures/Corrected angle - polar.pdf", plot= polar.corr.plot, width= 12, height= 8, units = 'cm')

# computing proportion to the RIGHT of the vertical
est.2.left <- results %>%
    dplyr::filter(Confidence > 0) %>%
    dplyr::mutate(est.2.left= true_angle<0) %>%
    dplyr::group_by(Observer) %>%
    dplyr::summarize(count= sum(est.2.left),
                     proportion= mean(est.2.left), 
                     ci.lower= binom::binom.exact(count, n(), conf.level = 0.99)$lower,
                     ci.upper= binom::binom.exact(count, n(), conf.level = 0.99)$upper)

est.2.left.corr.plot <- ggplot(data= est.2.left, aes(x= Observer, y= proportion, 
                                                    ymin= ci.lower, ymax= ci.upper, 
                                                    color= Observer)) + 
    geom_errorbar() + 
    geom_point()+
    scale_x_discrete(limits = rev(levels(results$Observer))) +
    ylim(0, 1)
    
print(est.2.left.corr.plot)
# ggsave(file="Generated figures/Corrected angle - estimates proportion.pdf", plot= est.2.left.corr.plot, width= 12, height= 8, units = 'cm')<jupyter_output><empty_output><jupyter_text>Distributions of the relative angle__Figure 1F__ in the manuscript<jupyter_code>estimates <- results %>%
    dplyr::filter((Confidence > 0) & (true_angle!=0)) %>%
    dplyr::mutate(estimate.side= sign(true_angle),
                  relative.angle= abs(true_angle*180/pi),
                  estimate.side= factor(estimate.side, levels= c(-1, 1), labels= c('left', 'right')))

# dist.diff <- ks.test(estimates$relative.angle[estimates$estimate.side=='left'], estimates$relative.angle[estimates$estimate.side=='right'])

dist.diff<- wilcox.test(relative.angle ~ estimate.side, data= estimates)
    
relative.raw.plot <- ggplot(data= estimates, aes(x= relative.angle, fill= estimate.side)) + 
    geom_histogram(aes(y= ..density../sum(..density..)), bins= 40, alpha= 0.5, position="identity")+
#     stat_ecdf(geom = "step")+
    ylab("Probability density") + 
    xlab("Relative angle, °") + 
    scale_x_continuous(breaks= seq(0, 180, 45), limits = c(0, 180))+
#     ggtitle(sprintf('Kolmogorov-Smirnov D= %.2f, p= %g', dist.diff$statistic, dist.diff$p.value))
    ggtitle(sprintf("Wilcoxon's W= %f, p= %g", dist.diff$statistic, dist.diff$p.value))
print(relative.raw.plot)
# ggsave(file="Generated figures/Relative angle - pdf.pdf", plot= relative.raw.plot, width= 12, height= 8, units = 'cm')

cdf.raw.plot <- ggplot(data= estimates, aes(x= relative.angle, color= estimate.side)) + 
    stat_ecdf(geom = "step")+
    ylab("Probability density") + 
    xlab("Relative angle, °")+
    scale_x_continuous(breaks= seq(0, 180, 45), limits = c(0, 180))
print(cdf.raw.plot)
# ggsave(file="Generated figures/Relative angle - cdf.pdf", plot= cdf.raw.plot, width= 12, height= 8, units = 'cm')<jupyter_output><empty_output><jupyter_text>Confidence distribution__Figure S3A__ in the manuscript<jupyter_code>conf.dist <- results %>%
    dplyr::group_by(Observer, Confidence) %>%
    dplyr::summarize(count= n()) %>%
    dplyr::ungroup() %>%
    dplyr::group_by(Observer) %>%
    dplyr::mutate(count = 100*count/sum(count))

conf.plot <- ggplot(data= conf.dist, aes(x= Confidence, y= count, color= Observer, group= Confidence)) + 
    geom_boxplot(outlier.shape = NA) + 
    geom_jitter(width= 0.2) + 
    ylab('Trial proportion') + 
    xlab('Report confidence') + 
    scale_x_continuous(breaks= 0:7, labels = c('-', 1:7)) + 
    theme(panel.grid.minor.x = element_blank(), legend.position = 'none')

print(conf.plot)
# ggsave(file="Generated figures/Response confidence.pdf", plot= conf.plot, width= 8, height= 8, units = 'cm')<jupyter_output><empty_output><jupyter_text>Consistency as the function of confidence__Figure S3B__ in the manuscript.<jupyter_code>paintings <- results %>%
    dplyr::filter(Confidence>0) %>%
    dplyr::group_by(local_filename) %>%
    dplyr::filter(n()>2) %>%
    dplyr::summarize(estimate.std= sd(true_angle*180/pi, na.rm= TRUE),
                     confidence= round(mean(Confidence)))

mean.per.confidence.level <- paintings %>%
    group_by(confidence) %>%
    summarize(median.std= median(estimate.std))

# paintings

confidence.vs.variance.plot <- ggplot(data= paintings, aes(x= confidence, y= estimate.std, group= confidence)) + 
    geom_boxplot() + 
    xlab('Confidence') +
    ylab('Standard deviation of estimates') + 
    scale_y_continuous(breaks= c(seq(0, 180, 45), mean.per.confidence.level$median.std))
print(confidence.vs.variance.plot)
# ggsave(file="Generated figures/Estimates consistency based on confidence.pdf", plot= confidence.vs.variance.plot, width= 8, height= 8, units = 'cm')

summary(lm(estimate.std ~ confidence , data= paintings))<jupyter_output><empty_output><jupyter_text>Computing an average estimate for each paintingThis is then used as for the classifier script<jupyter_code>paintings.with.an.estimate <- results %>%
    dplyr::filter(Confidence>0, year_unambiguous>1000) %>%
    dplyr::group_by(local_filename) %>%
    dplyr::summarize(year= year_unambiguous[1], 
                     estimate= mean(true_angle), 
                     estimate.side= sign(estimate),
                     confidence= mean(Confidence))
write.csv2(paintings.with.an.estimate, file.path('Data', 'paintings with estimates.csv'), row.names= FALSE)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15626851773469905, 'fraction_numerical': 0.020231947854059087, 'mean_word_length': 3.4699205448354142, 'pattern_counts': {'":': 0, '<': 70, '<?xml version=': 0, '>': 80, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '460802', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 4308, 'n_tokens_neox': 3922, 'n_words': 754, 'path': '2r. Overall preference for the light source location .ipynb', 'repo_name': 'alexander-pastukhov/top-left-light-10K', 'size': '11813'}