File size: 6,278 Bytes
d79174d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# General functions and routines used in the dashboard

import streamlit as st
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from PIL import Image


##### Dashboard main page
def prompt_to_csv(df):
    df_download = df
    df_download['Filename']='p'+df_download['ID'].astype('str')+'_1.png'
    df_download = df[['Prompt','Filename']].drop_duplicates(subset='Filename')
    return df_download.to_csv().encode('utf-8')

##### Manual assessment

def add_previous_manual_assessments():
    '''
    This is a routine to allow the user to upload prior manual ratings and override
    current ratings. This way the user can restart a manual assessment.
    '''
    # Create dict to translate uploaded score into str format used during manual assessment
    Bool_str_dict = {True:'Yes',False:'No'}

    st.subheader('Add previous assessments')
    st.write('Upload results of previous assessment (as downloaded from summary page) to add these results and skip these images in your current manual assessment. Note that you can only add results for images which you have uploaded using the same file name.')

    uploaded_ratings = st.file_uploader('Select .csv for upload', accept_multiple_files=False)
    if uploaded_ratings != None:
        try:
            uploaded_ratings_df = pd.read_csv(uploaded_ratings)
            overlapping_files_df =pd.merge(st.session_state['eval_df'],uploaded_ratings_df,on='File_name',how='inner')
            st.write('Number of matching file names found: '+ str(len(overlapping_files_df)))
            st.write('Click "Add results" button to add / override current ratings with uploaded ratings.')
        except UnicodeDecodeError:
            st.write('WARNING: The uploaded file has to be a .csv downloaded from the "Assessment summary" page.')


    submitted = st.button("Add results")
    if submitted:
        try:
            for row in uploaded_ratings_df.itertuples():
                st.session_state['eval_df'].loc[
                    st.session_state['eval_df']['File_name']==row.File_name,'manual_eval']=True
                st.session_state['eval_df'].loc[
                    st.session_state['eval_df']['File_name']==row.File_name,'manual_eval_completed']=True
                st.session_state['eval_df'].loc[
                    st.session_state['eval_df']['File_name']==row.File_name,'manual_eval_task_score']=Bool_str_dict[row.Score]

            # Reset page after ratings were submitted
            st.experimental_rerun()
        except NameError:
            st.write('You need to upload a .csv file before you can add results.')


##### Assessment summary
def plot_style_simple(results_df, return_table = False):
    '''
    Simple plot function for plotting just one dataframe of results
    '''
    eval_sum = results_df.groupby('Task')['Score'].sum()
    eval_count = results_df.groupby('Task')['Score'].count()
    eval_share = (eval_sum/eval_count)*100

    if return_table:
        return_series = results_df.groupby('Task')['Score'].sum()/results_df.groupby('Task')['Score'].count()*100
        return_series = return_series.rename('Percentage correct')
        return return_series

    # Add small amount to make the bars on plot not disappear
    eval_share = eval_share+1

    fig = plt.figure(figsize=(12, 3))
    sns.barplot(x=eval_share.index, y=eval_share.values, palette='GnBu')
    plt.xticks(rotation=-65)
    plt.ylabel('Percentage correct')
    plt.xlabel(' ')
    return fig

def plot_style_combined(results_df, uploaded_df = None, return_table=False):
    '''
    Plot function which can plot to dataframe for comparison
    '''
    # Create joined dataframe of results and uploadd_df
    uploaded_results_df = uploaded_df
    manual_results_df['Model']='Current'
    uploaded_results_df['Model']='Uploaded'
    results_df = pd.concat([manual_results_df,uploaded_results_df])

    # Create scores for plot
    eval_sum = results_df.groupby(['Model','Task'])['Score'].sum()
    eval_count = results_df.groupby(['Model','Task'])['Score'].count()
    eval_share = (eval_sum/eval_count)*100
    eval_share = eval_share.reset_index()

    if return_table:
        return_series = results_df.groupby(['Task','Model'])['Score'].sum()/results_df.groupby(['Task','Model'])['Score'].count()*100
        return_series = return_series.rename('Percentage correct')
        return return_series

    # Add small amount to make the bars on plot not disappear
    eval_share['Score'] = eval_share['Score']+1

    # Create plot
    fig = plt.figure(figsize=(12, 3))
    sns.barplot(data=eval_share,x='Task',y='Score',hue='Model', palette='GnBu')
    plt.xticks(rotation=-65)
    plt.ylabel('Percentage correct')
    plt.xlabel(' ')
    return fig


def print_results_tabs(file_upload, results_df, file_upload_df=None):
    '''
    Routine used to give user the choice between showing results as bar chart or table
    '''
    # Create a tab for bar chart and one for table data
    tab1, tab2 = st.tabs(["Bar chart", "Data table"])
    with tab1:
        # If df was uploaded for comparison, we create comparison plot, else simple plot
        if file_upload == None:
            fig = plot_style_simple(results_df)
            st.pyplot(fig)
        else:
            fig = plot_style_combined(results_df,file_upload_df)
            st.pyplot(fig)

    with tab2:
        # If df was uploaded for comparison, we create comparison table, else simple table
        if file_upload == None:
            table = plot_style_simple(results_df, return_table=True)
            st.write(table)
        else:
            table = plot_style_combined(results_df,file_upload_df, return_table=True)
            st.write(table)


def pre_assessment_visualisation(type_str):
    '''
    Routine used to allow user to visualise uploaded results before completing any assessments
    '''
    st.write('Complete {0} assessment or upload .csv with saved {0} assessment to generate summary.'.format(type_str))

    # Display file uploader
    file_upload = st.file_uploader("Upload .csv with saved {0} assessment to plot prior results.".format(type_str))
    if file_upload != None:
        file_upload_df = pd.read_csv(file_upload).copy()
        print_results_tabs(file_upload=None, results_df=file_upload_df)