Mercurial > hg > webaudioevaluationtool
comparison scripts/generate_report.py @ 1072:2ea78697aadf
Scripts: comment_parser and score_parser start new CSV files each time; various plots added to generated PDF report
author | Brecht De Man <BrechtDeMan@users.noreply.github.com> |
---|---|
date | Thu, 20 Aug 2015 11:29:29 +0200 |
parents | e2dd3105a84c |
children | a76081548018 |
comparison
equal
deleted
inserted
replaced
1071:e2dd3105a84c | 1072:2ea78697aadf |
---|---|
9 import shlex # for calling pdflatex | 9 import shlex # for calling pdflatex |
10 import matplotlib.pyplot as plt # plots | 10 import matplotlib.pyplot as plt # plots |
11 import numpy as np # numbers | 11 import numpy as np # numbers |
12 | 12 |
13 # Command line arguments | 13 # Command line arguments |
14 assert len(sys.argv)<3, "evaluation_stats takes at most 1 command line argument\n"+\ | 14 assert len(sys.argv)<4, "evaluation_stats takes at most 2 command line argument\n"+\ |
15 "Use: python evaluation_stats.py [results_folder]" | 15 "Use: python generate_report.py [results_folder] [no_render | -nr]" |
16 | |
17 render_figures = True | |
16 | 18 |
17 # XML results files location | 19 # XML results files location |
18 if len(sys.argv) == 1: | 20 if len(sys.argv) == 1: |
19 folder_name = "../saves" # Looks in 'saves/' folder from 'scripts/' folder | 21 folder_name = "../saves" # Looks in 'saves/' folder from 'scripts/' folder |
20 print "Use: python evaluation_stats.py [results_folder]" | 22 print "Use: python generate_report.py [results_folder] [no_render | -nr]" |
21 print "Using default path: " + folder_name | 23 print "Using default path: " + folder_name |
22 elif len(sys.argv) == 2: | 24 elif len(sys.argv) == 2: |
23 folder_name = sys.argv[1] # First command line argument is folder | 25 folder_name = sys.argv[1] # First command line argument is folder |
26 elif len(sys.argv) == 3: | |
27 folder_name = sys.argv[1] # First command line argument is folder | |
28 assert sys.argv[2] in ('no_render','-nr'), "Second argument not recognised. \n" +\ | |
29 "Use: python generate_report.py [results_folder] [no_render | -nr]" | |
30 # Second command line argument is [no_render | -nr] | |
31 render_figures = False | |
32 | |
33 | |
34 #TODO add 'skip regenerating figures' | |
24 | 35 |
25 # Turn number of seconds (int) to '[minutes] min [seconds] s' (string) | 36 # Turn number of seconds (int) to '[minutes] min [seconds] s' (string) |
26 def seconds2timestr(time_in_seconds): | 37 def seconds2timestr(time_in_seconds): |
27 time_in_minutes = int(time_in_seconds/60) | 38 time_in_minutes = int(time_in_seconds/60) |
28 remaining_seconds = int(time_in_seconds%60) | 39 remaining_seconds = int(time_in_seconds%60) |
37 total_not_moved = 0 | 48 total_not_moved = 0 |
38 time_per_page_accum = 0 | 49 time_per_page_accum = 0 |
39 | 50 |
40 # arrays initialisation | 51 # arrays initialisation |
41 page_names = [] | 52 page_names = [] |
53 real_page_names = [] # regardless of differing numbers of fragments | |
54 subject_count = [] # subjects per audioholder name | |
42 page_count = [] | 55 page_count = [] |
43 duration_page = [] # duration of experiment in function of page content | 56 duration_page = [] # duration of experiment in function of page content |
44 duration_order = [] # duration of experiment in function of page number | 57 duration_order = [] # duration of experiment in function of page number |
45 fragments_per_page = [] # number of fragments for corresponding page | 58 fragments_per_page = [] # number of fragments for corresponding page |
59 | |
60 # survey stats | |
61 gender = [] | |
62 age = [] | |
46 | 63 |
47 # get username if available | 64 # get username if available |
48 for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): | 65 for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): |
49 user = os.environ.get(name) | 66 user = os.environ.get(name) |
50 if user: | 67 if user: |
54 | 71 |
55 | 72 |
56 # begin LaTeX document | 73 # begin LaTeX document |
57 header = r'''\documentclass[11pt, oneside]{article} | 74 header = r'''\documentclass[11pt, oneside]{article} |
58 \usepackage{geometry} | 75 \usepackage{geometry} |
59 \geometry{letterpaper} | 76 \geometry{a4paper} |
60 \usepackage[parfill]{parskip} | 77 \usepackage[parfill]{parskip} % empty line instead of indent |
61 \usepackage{graphicx} | 78 \usepackage{graphicx} % figures |
79 \usepackage{hyperref} | |
80 \usepackage{tikz} % pie charts | |
62 \title{Report} | 81 \title{Report} |
63 \author{'''+\ | 82 \author{'''+\ |
64 user+\ | 83 user+\ |
65 r'''} | 84 r'''} |
66 \graphicspath{{'''+\ | 85 \graphicspath{{'''+\ |
67 folder_name+\ | 86 folder_name+\ |
68 r'''/}} | 87 r'''/}} |
88 %\setcounter{section}{-1} % Summary section 0 so number of sections equals number of files | |
69 \begin{document} | 89 \begin{document} |
70 \maketitle | 90 \maketitle |
91 This is an automatically generated report using the `generate\_report.py' Python script | |
92 included with the Web Audio Evaluation Tool \cite{WAET} distribution which can be found | |
93 at \texttt{code.soundsoftware.ac.uk/projects/webaudioevaluationtool}. | |
71 \tableofcontents | 94 \tableofcontents |
95 | |
72 ''' | 96 ''' |
73 | 97 |
74 footer = '\end{document}' | 98 footer = r'''\begin{thebibliography}{9} |
99 \bibitem{WAET} % reference to accompanying publication | |
100 Nicholas Jillings, Brecht De Man, David Moffat and Joshua D. Reiss, | |
101 ``Web Audio Evaluation Tool: A browser-based listening test environment,'' | |
102 presented at the 12th Sound and Music Computing Conference, July 2015. | |
103 \end{thebibliography} | |
104 \end{document}''' | |
75 | 105 |
76 body = '' | 106 body = '' |
77 | 107 |
78 # generate images for later use | 108 # generate images for later use |
79 subprocess.call("timeline_view_movement.py", shell=True) | 109 if render_figures: |
110 subprocess.call("python timeline_view_movement.py", shell=True) | |
111 subprocess.call("python score_parser.py", shell=True) | |
112 subprocess.call("python score_plot.py", shell=True) | |
80 | 113 |
81 # get every XML file in folder | 114 # get every XML file in folder |
82 files_list = os.listdir(folder_name) | 115 files_list = os.listdir(folder_name) |
83 for file in files_list: # iterate over all files in files_list | 116 for file in files_list: # iterate over all files in files_list |
84 if file.endswith(".xml"): # check if XML file | 117 if file.endswith(".xml"): # check if XML file |
92 # reset for new subject | 125 # reset for new subject |
93 total_duration = 0 | 126 total_duration = 0 |
94 page_number = 0 | 127 page_number = 0 |
95 | 128 |
96 individual_table = '' # table with stats for this individual test file | 129 individual_table = '' # table with stats for this individual test file |
130 timeline_plots = '' # plots of timeline (movements and plays) | |
131 | |
132 # DEMO survey stats | |
133 # get gender | |
134 this_subjects_gender = root.find("./posttest/radio/[@id='gender']") | |
135 if this_subjects_gender is not None: | |
136 gender.append(this_subjects_gender.get("name")) | |
137 else: | |
138 gender.append('UNAVAILABLE') | |
139 # get age | |
140 this_subjects_age = root.find("./posttest/number/[@id='age']") | |
141 if this_subjects_age is not None: | |
142 age.append(this_subjects_age.text) | |
97 | 143 |
98 # get list of all page names | 144 # get list of all page names |
99 for audioholder in root.findall("./audioholder"): # iterate over pages | 145 for audioholder in root.findall("./audioholder"): # iterate over pages |
100 page_name = audioholder.get('id') # get page name | 146 page_name = audioholder.get('id') # get page name |
101 | 147 |
147 # number of audio element markers not moved | 193 # number of audio element markers not moved |
148 if not_moved > 1: | 194 if not_moved > 1: |
149 body += '\\emph{\\textbf{ATTENTION: '+str(not_moved)+' markers were not moved in '+page_name+'!}} \\\\ \n' | 195 body += '\\emph{\\textbf{ATTENTION: '+str(not_moved)+' markers were not moved in '+page_name+'!}} \\\\ \n' |
150 if not_moved == 1: | 196 if not_moved == 1: |
151 body += '\\emph{\\textbf{ATTENTION: one marker was not moved in '+page_name+'!}} \\\\ \n' | 197 body += '\\emph{\\textbf{ATTENTION: one marker was not moved in '+page_name+'!}} \\\\ \n' |
152 | |
153 #TODO which one not moved/listened to? | 198 #TODO which one not moved/listened to? |
154 | 199 |
155 # PRINT song-specific statistic | 200 # PRINT song-specific statistic |
156 individual_table += page_name+'&'+\ | 201 individual_table += page_name+'&'+\ |
157 str(number_of_comments) + '/' +\ | 202 str(number_of_comments) + '/' +\ |
162 img_path = 'timelines_movement/'+file[:-4]+'-'+page_name+'.pdf' | 207 img_path = 'timelines_movement/'+file[:-4]+'-'+page_name+'.pdf' |
163 | 208 |
164 # check if available | 209 # check if available |
165 if os.path.isfile(folder_name+'/'+img_path): | 210 if os.path.isfile(folder_name+'/'+img_path): |
166 # SHOW timeline image | 211 # SHOW timeline image |
167 body += r'''\begin{figure}[htbp] | 212 timeline_plots += '\\includegraphics[width=\\textwidth]{'+\ |
168 \begin{center} | 213 folder_name+'/'+img_path+'}\n\n' |
169 \includegraphics[width=\textwidth]{'''+\ | |
170 folder_name+'/'+img_path+\ | |
171 r'''} | |
172 \caption{Timeline of '''+\ | |
173 page_name+' by '+ file[:-4].capitalize() +\ | |
174 r'''.} | |
175 \end{center} | |
176 \end{figure} | |
177 ''' | |
178 | 214 |
179 # keep track of duration in function of page index | 215 # keep track of duration in function of page index |
180 if len(duration_order)>page_number: | 216 if len(duration_order)>page_number: |
181 duration_order[page_number].append(duration) | 217 duration_order[page_number].append(duration) |
182 else: | 218 else: |
183 duration_order.append([duration]) | 219 duration_order.append([duration]) |
184 | 220 |
185 # keep list of audioholder ids and count how many times each audioholder id | 221 # keep list of audioholder ids and count how many times each audioholder id |
186 # was tested, how long it took, and how many fragments there were (if number of | 222 # was tested, how long it took, and how many fragments there were |
187 # fragments is different, store as different audioholder id) | 223 # (if number of fragments is different, store as different audioholder id) |
188 if page_name in page_names: | 224 if page_name in page_names: |
189 page_index = page_names.index(page_name) # get index | 225 page_index = page_names.index(page_name) # get index |
190 # check if number of audioelements the same | 226 # check if number of audioelements the same |
191 if len(audioelements) == fragments_per_page[page_index]: | 227 if len(audioelements) == fragments_per_page[page_index]: |
192 page_count[page_index] += 1 | 228 page_count[page_index] += 1 |
205 else: | 241 else: |
206 page_names.append(page_name) | 242 page_names.append(page_name) |
207 page_count.append(1) | 243 page_count.append(1) |
208 duration_page.append([duration]) | 244 duration_page.append([duration]) |
209 fragments_per_page.append(len(audioelements)) | 245 fragments_per_page.append(len(audioelements)) |
210 | 246 |
247 # number of subjects per audioholder regardless of differing numbers of | |
248 # fragments (for inclusion in box plots) | |
249 if page_name in real_page_names: | |
250 page_index = real_page_names.index(page_name) # get index | |
251 subject_count[page_index] += 1 | |
252 else: | |
253 real_page_names.append(page_name) | |
254 subject_count.append(1) | |
255 | |
211 # bookkeeping | 256 # bookkeeping |
212 page_number += 1 # increase page count for this specific test | 257 page_number += 1 # increase page count for this specific test |
213 number_of_pages += 1 # increase total number of pages | 258 number_of_pages += 1 # increase total number of pages |
214 time_per_page_accum += duration # total duration (for average time spent per page) | 259 time_per_page_accum += duration # total duration (for average time spent per page) |
215 | 260 |
221 r'''\hline | 266 r'''\hline |
222 \textbf{TOTAL} & & \textbf{'''+\ | 267 \textbf{TOTAL} & & \textbf{'''+\ |
223 seconds2timestr(total_duration)+\ | 268 seconds2timestr(total_duration)+\ |
224 r'''}\\ | 269 r'''}\\ |
225 \hline | 270 \hline |
226 \end{tabular}''' | 271 \end{tabular} |
272 | |
273 ''' | |
274 # PRINT timeline plots | |
275 body += timeline_plots | |
227 | 276 |
228 # join to footer | 277 # join to footer |
229 footer = body + footer | 278 footer = body + footer |
230 | 279 |
231 # empty body again | 280 # empty body again |
232 body = '' | 281 body = '' |
233 | 282 |
234 # PRINT summary of everything (at start) | 283 # PRINT summary of everything (at start) |
235 body += '\section{Summary}\n' | 284 # unnumbered so that number of sections equals number of files |
285 body += '\section*{Summary}\n\\addcontentsline{toc}{section}{Summary}' | |
236 | 286 |
237 # PRINT table with statistics | 287 # PRINT table with statistics |
238 body += '\\begin{tabular}{ll}' | 288 body += '\\begin{tabular}{ll}' |
239 body += r'Number of XML files: &' + str(number_of_XML_files) + r'\\' | 289 body += r'Number of XML files: &' + str(number_of_XML_files) + r'\\' |
240 body += r'Number of pages: &' + str(number_of_pages) + r'\\' | 290 body += r'Number of pages: &' + str(number_of_pages) + r'\\' |
244 body += r'Number of unplayed fragments: &' + str(total_not_played) +\ | 294 body += r'Number of unplayed fragments: &' + str(total_not_played) +\ |
245 " (" + str(round(100.0*total_not_played/number_of_fragments,2)) + r"\%)\\" | 295 " (" + str(round(100.0*total_not_played/number_of_fragments,2)) + r"\%)\\" |
246 body += r'Number of unmoved markers: &' + str(total_not_moved) +\ | 296 body += r'Number of unmoved markers: &' + str(total_not_moved) +\ |
247 " (" + str(round(100.0*total_not_moved/number_of_fragments,2)) + r"\%)\\" | 297 " (" + str(round(100.0*total_not_moved/number_of_fragments,2)) + r"\%)\\" |
248 body += r'Average time per page: &' + seconds2timestr(time_per_page_accum/number_of_pages) + r"\\" | 298 body += r'Average time per page: &' + seconds2timestr(time_per_page_accum/number_of_pages) + r"\\" |
249 | |
250 | |
251 # Pages and number of times tested | |
252 page_count_strings = list(str(x) for x in page_count) | |
253 count_list = page_names + page_count_strings | |
254 count_list[::2] = page_names | |
255 count_list[1::2] = page_count_strings | |
256 #body += r'Pages tested: &' + str(count_list) + r"\\" | |
257 | |
258 body += '\\end{tabular} \\vspace{1.5cm} \\\\ \n' | 299 body += '\\end{tabular} \\vspace{1.5cm} \\\\ \n' |
259 | 300 |
260 # Average duration for first, second, ... page | 301 # Average duration for first, second, ... page |
261 body += " \\vspace{.5cm} Average duration per page (see also Figure \\ref{fig:avgtimeperpage}): \\\\ \n" | 302 body += " \\vspace{.5cm} Average duration per page (see also Figure \\ref{fig:avgtimeperpage}): \\\\ \n" |
262 body += r'''\begin{tabular}{lll} | 303 body += r'''\begin{tabular}{lll} |
270 tpp_averages.append(sum(duration_order[page_number])/len(duration_order[page_number])) | 311 tpp_averages.append(sum(duration_order[page_number])/len(duration_order[page_number])) |
271 | 312 |
272 body += '\\end{tabular} \\vspace{1.5cm} \\\\ \n' | 313 body += '\\end{tabular} \\vspace{1.5cm} \\\\ \n' |
273 | 314 |
274 # SHOW bar plot of average time per page | 315 # SHOW bar plot of average time per page |
275 plt.bar(range(1,len(duration_order)+1), tpp_averages) | 316 plt.bar(range(1,len(duration_order)+1), np.array(tpp_averages)/60) |
276 plt.xlabel('Page') | 317 plt.xlabel('Page order') |
277 plt.xlim(.8, len(duration_order)+1) | 318 plt.xlim(.8, len(duration_order)+1) |
278 plt.xticks(np.arange(1,len(duration_order)+1)+.4, range(1,len(duration_order)+1)) | 319 plt.xticks(np.arange(1,len(duration_order)+1)+.4, range(1,len(duration_order)+1)) |
279 plt.ylabel('Time [seconds]') | 320 plt.ylabel('Average time [minutes]') |
280 plt.savefig(folder_name+"/time_per_page.pdf", bbox_inches='tight') | 321 plt.savefig(folder_name+"/time_per_page.pdf", bbox_inches='tight') |
281 plt.close() | 322 plt.close() |
282 body += r'''\begin{figure}[htbp] | |
283 \begin{center} | |
284 \includegraphics[width=\textwidth]{'''+\ | |
285 folder_name+"/time_per_page.pdf"+\ | |
286 r'''} | |
287 \caption{Average time spent per audioholder page.} | |
288 \label{fig:avgtimeperpage} | |
289 \end{center} | |
290 \end{figure} | |
291 ''' | |
292 #TODO add error bars | 323 #TODO add error bars |
293 | 324 |
294 | 325 |
295 # Sort pages by number of audioelements, then by duration | 326 # Sort pages by number of audioelements, then by duration |
296 | 327 |
304 # combine and sort in function of number of audioelements and duration | 335 # combine and sort in function of number of audioelements and duration |
305 combined_list = [page_names, average_duration_page, fragments_per_page, number_of_subjects_page] | 336 combined_list = [page_names, average_duration_page, fragments_per_page, number_of_subjects_page] |
306 combined_list = sorted(zip(*combined_list), key=operator.itemgetter(1, 2)) # sort | 337 combined_list = sorted(zip(*combined_list), key=operator.itemgetter(1, 2)) # sort |
307 | 338 |
308 # Show average duration for all songs | 339 # Show average duration for all songs |
309 body += r'''\vspace{.5cm} Average duration per audioholder: \\ | 340 body += r'''\vspace{.5cm} Average duration per audioholder (see also Figure \ref{fig:avgtimeperaudioholder}): \\ |
310 \begin{tabular}{llll} | 341 \begin{tabular}{llll} |
311 \textbf{Audioholder} & \textbf{Duration} & \textbf{\# subjects} & \textbf{\# fragments} \\ | 342 \textbf{Audioholder} & \textbf{Duration} & \textbf{\# subjects} & \textbf{\# fragments} \\ |
312 ''' | 343 ''' |
344 audioholder_names_ordered = [] | |
345 average_duration_audioholder_ordered = [] | |
346 number_of_subjects = [] | |
313 for page_index in range(len(page_names)): | 347 for page_index in range(len(page_names)): |
348 audioholder_names_ordered.append(combined_list[page_index][0]) | |
349 average_duration_audioholder_ordered.append(combined_list[page_index][1]) | |
350 number_of_subjects.append(combined_list[page_index][3]) | |
314 body += combined_list[page_index][0] + "&" +\ | 351 body += combined_list[page_index][0] + "&" +\ |
315 seconds2timestr(combined_list[page_index][1]) + "&" +\ | 352 seconds2timestr(combined_list[page_index][1]) + "&" +\ |
316 str(combined_list[page_index][3]) + "&" +\ | 353 str(combined_list[page_index][3]) + "&" +\ |
317 str(combined_list[page_index][2]) + r"\\" | 354 str(combined_list[page_index][2]) + r"\\" |
318 body += '\\end{tabular}\n' | 355 body += '\\end{tabular}\n' |
319 | 356 |
357 # SHOW bar plot of average time per page | |
358 plt.bar(range(1,len(audioholder_names_ordered)+1), np.array(average_duration_audioholder_ordered)/60) | |
359 plt.xlabel('Audioholder') | |
360 plt.xlim(.8, len(audioholder_names_ordered)+1) | |
361 plt.xticks(np.arange(1,len(audioholder_names_ordered)+1)+.4, audioholder_names_ordered, rotation=90) | |
362 plt.ylabel('Average time [minutes]') | |
363 plt.savefig(folder_name+"/time_per_audioholder.pdf", bbox_inches='tight') | |
364 plt.close() | |
365 | |
366 # SHOW bar plot of average time per page | |
367 plt.bar(range(1,len(audioholder_names_ordered)+1), number_of_subjects) | |
368 plt.xlabel('Audioholder') | |
369 plt.xlim(.8, len(audioholder_names_ordered)+1) | |
370 plt.xticks(np.arange(1,len(audioholder_names_ordered)+1)+.4, audioholder_names_ordered, rotation=90) | |
371 plt.ylabel('Number of subjects') | |
372 ax = plt.gca() | |
373 ylims = ax.get_ylim() | |
374 yint = np.arange(int(np.floor(ylims[0])), int(np.ceil(ylims[1]))+1) | |
375 plt.yticks(yint) | |
376 plt.savefig(folder_name+"/subjects_per_audioholder.pdf", bbox_inches='tight') | |
377 plt.close() | |
378 | |
379 # SHOW both figures | |
380 body += r'''\begin{figure}[htbp] | |
381 \begin{center} | |
382 \includegraphics[width=.65\textwidth]{'''+\ | |
383 folder_name+"/time_per_page.pdf"+\ | |
384 r'''} | |
385 \caption{Average time spent per page.} | |
386 \label{fig:avgtimeperpage} | |
387 \end{center} | |
388 \end{figure} | |
389 ''' | |
390 body += r'''\begin{figure}[htbp] | |
391 \begin{center} | |
392 \includegraphics[width=.65\textwidth]{'''+\ | |
393 folder_name+"/time_per_audioholder.pdf"+\ | |
394 r'''} | |
395 \caption{Average time spent per audioholder.} | |
396 \label{fig:avgtimeperaudioholder} | |
397 \end{center} | |
398 \end{figure} | |
399 ''' | |
400 body += r'''\begin{figure}[htbp] | |
401 \begin{center} | |
402 \includegraphics[width=.65\textwidth]{'''+\ | |
403 folder_name+"/subjects_per_audioholder.pdf"+\ | |
404 r'''} | |
405 \caption{Number of subjects per audioholder.} | |
406 \label{fig:avgtimeperaudioholder} | |
407 \end{center} | |
408 \end{figure} | |
409 ''' | |
410 #TODO add error bars | |
411 #TODO layout of figures | |
412 | |
413 # SHOW boxplot per audioholder | |
414 #TODO order in decreasing order of participants | |
415 for audioholder_name in page_names: # get each name | |
416 # plot boxplot if exists (not so for the 'alt' names) | |
417 if os.path.isfile(folder_name+'/ratings/'+audioholder_name+'-ratings-box.pdf'): | |
418 body += r'''\begin{figure}[htbp] | |
419 \begin{center} | |
420 \includegraphics[width=.65\textwidth]{'''+\ | |
421 folder_name+"/ratings/"+audioholder_name+'-ratings-box.pdf'+\ | |
422 r'''} | |
423 \caption{Box plot of ratings for audioholder '''+\ | |
424 audioholder_name+' ('+str(subject_count[real_page_names.index(audioholder_name)])+\ | |
425 ''' participants).} | |
426 \label{fig:avgtimeperpage} | |
427 \end{center} | |
428 \end{figure} | |
429 ''' | |
430 | |
431 # DEMO pie chart of gender distribution among subjects | |
432 genders = ['male', 'female', 'other', 'preferNotToSay', 'UNAVAILABLE'] | |
433 # TODO: get the above automatically | |
434 gender_distribution = '' | |
435 for item in genders: | |
436 number = gender.count(item) | |
437 if number>0: | |
438 gender_distribution += str("{:.2f}".format((100.0*number)/len(gender)))+\ | |
439 '/'+item.capitalize()+' ('+str(number)+'),\n' | |
440 | |
441 body += r''' | |
442 \def\angle{0} | |
443 \def\radius{3} | |
444 \def\cyclelist{{"orange","blue","red","green"}} | |
445 \newcount\cyclecount \cyclecount=-1 | |
446 \newcount\ind \ind=-1 | |
447 \begin{figure}[htbp] | |
448 \begin{center}\begin{tikzpicture}[nodes = {font=\sffamily}] | |
449 \foreach \percent/\name in {'''+\ | |
450 gender_distribution+\ | |
451 r'''} {\ifx\percent\empty\else % If \percent is empty, do nothing | |
452 \global\advance\cyclecount by 1 % Advance cyclecount | |
453 \global\advance\ind by 1 % Advance list index | |
454 \ifnum6<\cyclecount % If cyclecount is larger than list | |
455 \global\cyclecount=0 % reset cyclecount and | |
456 \global\ind=0 % reset list index | |
457 \fi | |
458 \pgfmathparse{\cyclelist[\the\ind]} % Get color from cycle list | |
459 \edef\color{\pgfmathresult} % and store as \color | |
460 % Draw angle and set labels | |
461 \draw[fill={\color!50},draw={\color}] (0,0) -- (\angle:\radius) | |
462 arc (\angle:\angle+\percent*3.6:\radius) -- cycle; | |
463 \node at (\angle+0.5*\percent*3.6:0.7*\radius) {\percent\,\%}; | |
464 \node[pin=\angle+0.5*\percent*3.6:\name] | |
465 at (\angle+0.5*\percent*3.6:\radius) {}; | |
466 \pgfmathparse{\angle+\percent*3.6} % Advance angle | |
467 \xdef\angle{\pgfmathresult} % and store in \angle | |
468 \fi | |
469 }; | |
470 \end{tikzpicture} | |
471 \caption{Representation of gender across subjects} | |
472 \label{default} | |
473 \end{center} | |
474 \end{figure} | |
475 ''' | |
476 # problem: some people entered twice? | |
477 | |
320 #TODO | 478 #TODO |
321 # time per page in function of number of fragments (plot) | 479 # time per page in function of number of fragments (plot) |
322 # time per participant in function of number of pages | 480 # time per participant in function of number of pages |
323 # plot total time for each participant | 481 # plot total time for each participant |
324 # plot total time | |
325 # show 'count' per page (in order) | 482 # show 'count' per page (in order) |
326 | 483 |
327 # clear up page_index <> page_count <> page_number confusion | 484 # clear up page_index <> page_count <> page_number confusion |
328 | 485 |
329 | 486 |
330 texfile = header+body+footer | 487 texfile = header+body+footer # add bits together |
331 | 488 |
332 # write TeX file | 489 # write TeX file |
333 with open(folder_name + '/' + 'test.tex','w') as f: | 490 with open(folder_name + '/' + 'Report.tex','w') as f: |
334 f.write(texfile) | 491 f.write(texfile) |
335 proc=subprocess.Popen(shlex.split('pdflatex -output-directory='+folder_name+' '+ folder_name + '/test.tex')) | 492 proc=subprocess.Popen(shlex.split('pdflatex -output-directory='+folder_name+' '+ folder_name + '/Report.tex')) |
336 proc.communicate() | 493 proc.communicate() |
337 # run again | 494 # run again |
338 proc=subprocess.Popen(shlex.split('pdflatex -output-directory='+folder_name+' '+ folder_name + '/test.tex')) | 495 proc=subprocess.Popen(shlex.split('pdflatex -output-directory='+folder_name+' '+ folder_name + '/Report.tex')) |
339 proc.communicate() | 496 proc.communicate() |
340 | 497 |
341 #TODO remove auxiliary LaTeX files | 498 #TODO remove auxiliary LaTeX files |
499 try: | |
500 os.remove(folder_name + '/' + 'Report.aux') | |
501 os.remove(folder_name + '/' + 'Report.log') | |
502 os.remove(folder_name + '/' + 'Report.out') | |
503 os.remove(folder_name + '/' + 'Report.toc') | |
504 except OSError: | |
505 pass | |
506 |