In [2]:
import os
import urllib, cStringIO

import pymongo as pm

import matplotlib
from matplotlib import pylab, mlab, pyplot
%matplotlib inline
from IPython.core.pylabtools import figsize, getfigs
plt = pyplot
import seaborn as sns
sns.set_context('poster')
sns.set_style('white')

import numpy as np
from __future__ import division
import scipy.stats as stats
import pandas as pd
import json
import re

from PIL import Image
import base64

import analysis_helpers as h
reload(h)


Out[2]:
<module 'analysis_helpers' from 'analysis_helpers.pyc'>

In [3]:
# directory & file hierarchy
iterationName = 'pilot2'
exp_path = './'
analysis_dir = os.getcwd()
data_dir = os.path.abspath(os.path.join(os.getcwd(),'../../..','data',exp_path))
exp_dir = './'
sketch_dir = os.path.abspath(os.path.join(os.getcwd(),'../../..','analysis',exp_path,'sketches','pilot2'))

In [4]:
# set vars 
auth = pd.read_csv('auth.txt', header = None) # this auth.txt file contains the password for the sketchloop user
pswd = auth.values[0][0]
user = 'sketchloop'
host = 'rxdhawkins.me' ## cocolab ip address

# have to fix this to be able to analyze from local
import pymongo as pm
conn = pm.MongoClient('mongodb://sketchloop:' + pswd + '@127.0.0.1')
db = conn['3dObjects']
coll = db['sketchpad_basic']

In [5]:
S = coll.find({ '$and': [{'iterationName':'pilot2'}, {'eventType': 'stroke'}]}).sort('time')
C = coll.find({ '$and': [{'iterationName':'pilot2'}, {'eventType': 'clickedObj'}]}).sort('time')
print str(S.count()) + ' stroke records in the database.'
print str(C.count()) + ' clickedObj records in the database.'


34620 stroke records in the database.
3220 clickedObj records in the database.

In [6]:
# print unique gameid's
unique_gameids = coll.find({ '$and': [{'iterationName':'pilot2'}, {'eventType': 'clickedObj'}]}).sort('time').distinct('gameid')
# print map(str,unique_gameids)

# filter out  records that match researcher ID's
jefan = ['A1MMCS8S8CTWKU','A1MMCS8S8CTWKV','A1MMCS8S8CTWKS']
hawkrobe = ['A1BOIDKD33QSDK']
researchers = jefan + hawkrobe
workers = [i for i in coll.find({'iterationName':'pilot2'}).distinct('workerId') if i not in researchers]

In [127]:
valid_gameids = []
for i,g in enumerate(unique_gameids):
    W = coll.find({ '$and': [{'gameid': g}]}).distinct('workerId')
    for w in W:
        if w in workers:
            X = coll.find({ '$and': [{'workerId': w}, {'gameid': g}]}).distinct('trialNum') ## # of trials completed
            eventType = coll.find({ '$and': [{'workerId': w}]}).distinct('eventType')
            print i, w[:4], len(X), str(eventType[0])
            if (str(eventType[0])=='clickedObj') & (len(X)==32):
                valid_gameids.append(g)
print '   ===========   '

## filter if the pair cheated by writing words or using other symbols
cheaty = ['8155-e46a25a3-9259-4b76-80e9-5bd79b6bdd97','6224-ab96ed5c-2a98-477c-aae2-7398b9e5b237',\
         '5595-a00b8109-1910-43c4-9f14-00eb4945ac70','1697-7ab5b295-fae8-4f62-8cbd-72aa0e23b10e']
motor = ['2829-820b338d-5720-4964-bd22-8ba38329569d'] # this person made multiples in several of their sketches, and appeared to suffer from strong tremors
unfiltered_gameids = valid_gameids
valid_gameids = [i for i in valid_gameids if i not in cheaty]
valid_gameids = [i for i in valid_gameids if i not in motor]

print str(len(valid_gameids)) + ' valid gameIDs (# complete games).'

df = pd.DataFrame([valid_gameids])
df = df.transpose()
df.columns=['valid_gameids']
df.to_csv('valid_gameids_pilot2.csv')

df = pd.DataFrame([unfiltered_gameids])
df = df.transpose()
df.columns=['unfiltered_gameids']
df.to_csv('unfiltered_gameids_pilot2.csv')


0  6 stroke
2 A3FC 32 stroke
2 A1PT 32 clickedObj
3 A2CF 32 stroke
3 A1DI 32 clickedObj
4 A2IK 32 stroke
4 A3AN 32 clickedObj
5 AW49 32 stroke
5 A2EY 32 clickedObj
6 A1LD 32 stroke
6 A2FY 32 clickedObj
7 A3T9 32 stroke
7 A3SD 32 clickedObj
8 A3P5 32 stroke
8 A2H0 32 clickedObj
9 A1YB 32 stroke
9 A1WJ 32 clickedObj
10 A1H9 32 stroke
10 A3W4 32 clickedObj
11 A2Q3 32 stroke
11 A30V 32 clickedObj
12 ANVX 32 stroke
12 A1F8 32 clickedObj
13 AMPM 2 stroke
13 AK77 1 clickedObj
14 A2AM 32 stroke
14 A2HG 32 clickedObj
15 A2ET 32 stroke
15 A3NV 32 clickedObj
16 A319 32 stroke
16 A1WI 32 clickedObj
17 AU34 32 stroke
17 A1JX 32 clickedObj
18 A3F6 32 stroke
18 A1KJ 32 clickedObj
19 A23B 32 stroke
19 A3NK 32 clickedObj
20 A1PM 32 stroke
20 A3BK 32 clickedObj
21 A1US 32 stroke
21 A3RX 32 clickedObj
22 A22Q 32 stroke
22 A1TG 32 clickedObj
23 AX9D 32 stroke
23 AO33 32 clickedObj
24 A3MY 32 stroke
24 A3MY 32 clickedObj
25 A1AK 32 stroke
25 A3JF 32 clickedObj
26 A2OJ 32 stroke
26 AFWK 32 clickedObj
27 A1A1 32 stroke
27 A3BU 32 clickedObj
28 A1QH 32 stroke
28 A4J7 32 clickedObj
29 A1WY 32 stroke
29 A1CU 32 clickedObj
30 A1H1 32 stroke
30 A27Z 32 clickedObj
31 A120 32 stroke
31 A12M 32 clickedObj
32 A161 5 stroke
32 A1H4 4 clickedObj
33 A3O5 32 stroke
33 ABL3 32 clickedObj
34 A3EW 32 stroke
34 ASIB 32 clickedObj
35 A1NZ 32 stroke
35 AYSG 32 clickedObj
36 A23B 32 stroke
36 A1SI 32 clickedObj
37 AAEZ 32 stroke
37 AZJT 32 clickedObj
38 A3F9 14 stroke
38 A2DL 13 clickedObj
39 AVQI 32 stroke
39 A3OB 32 clickedObj
40 A1MD 18 stroke
40 A397 18 clickedObj
41 AVI7 4 stroke
41 A1UJ 4 clickedObj
42 AVBR 32 stroke
42 A110 32 clickedObj
43 A19I 32 stroke
43 A3MY 32 clickedObj
44 AOTS 32 stroke
44 AQGQ 32 clickedObj
45 A1ZW 32 stroke
45 A1O4 32 clickedObj
46 A3TD 32 stroke
46 A2RK 32 clickedObj
47 A3EQ 32 stroke
47 A37E 32 clickedObj
48 A24U 32 stroke
48 A2OL 32 clickedObj
49 A35N 32 stroke
49 A1MT 32 clickedObj
50 A2PY 32 stroke
50 A24H 32 clickedObj
51 A23T 32 stroke
51 AHPQ 32 clickedObj
52 A3F9 32 stroke
52 A1US 32 clickedObj
53 A1W0 32 stroke
53 AII1 32 clickedObj
54 ATHS 32 stroke
54 A2BQ 32 clickedObj
55 A2EO 32 stroke
55 A2XV 32 clickedObj
56 A1OL 32 stroke
56 AOPX 32 clickedObj
57 A1ZI 32 stroke
57 A34Q 32 clickedObj
58 A2BP 32 stroke
58 A1VF 32 clickedObj
59 A2N3 32 stroke
59 A2GO 32 clickedObj
60 A14Y 32 stroke
60 A2M6 32 clickedObj
61 A38L 32 stroke
61 A3PP 32 clickedObj
62 A2M6 15 stroke
62 A3MI 14 clickedObj
63 AVCL 32 stroke
63 A166 32 clickedObj
64 A331 32 stroke
64 A1RZ 32 clickedObj
65 A3U6 32 stroke
65 A3EL 32 clickedObj
66 ATOV 32 stroke
66 A3TX 32 clickedObj
67 AE5Q 32 stroke
67 A1NL 32 clickedObj
68 A2LM 32 stroke
68 AOMT 32 clickedObj
69 A3IG 7 stroke
69 A1HY 6 clickedObj
70 A1F1 32 stroke
70 A2RP 32 clickedObj
71 A2V2 32 stroke
71 A1AK 32 clickedObj
72  1 stroke
73 A2LG 32 stroke
73 A1EK 32 clickedObj
74 A1VO 2 stroke
74 A2SM 1 clickedObj
75 A2MZ 32 stroke
75 A1L9 32 clickedObj
76 A2D7 32 stroke
76 A1LO 32 clickedObj
77 A18N 32 stroke
77 A1P3 32 clickedObj
78 A12I 32 stroke
78 AIW8 32 clickedObj
79 A31Y 32 stroke
79 A23K 32 clickedObj
80 A1P0 32 stroke
80 A1UZ 32 clickedObj
81 A230 32 stroke
81 A30B 32 clickedObj
82 AYLY 32 stroke
82 A3KE 32 clickedObj
83 A26M 32 stroke
83 AZJE 32 clickedObj
84 A3UE 32 stroke
84 A1Z3 32 clickedObj
85 A38N 32 stroke
85 AHZP 32 clickedObj
86 A1CS 32 stroke
86 ACGZ 32 clickedObj
87 A3RU 32 stroke
87 A1KR 32 clickedObj
88 A2FI 32 stroke
88 APF1 32 clickedObj
89 A1DI 32 stroke
89 A2AG 32 clickedObj
90 A1MS 32 stroke
90 AZ2H 32 clickedObj
91 AT3N 32 stroke
91 A2SS 32 clickedObj
92 A1YC 32 stroke
92 A1OP 32 clickedObj
93 A1Z2 32 stroke
93 A17P 32 clickedObj
94 A2AY 32 stroke
94 A3HN 32 clickedObj
95 A27A 32 stroke
95 A2WC 32 clickedObj
96 A2Z7 32 stroke
96 A1DL 32 clickedObj
97 ABEJ 32 stroke
97 A385 32 clickedObj
98 A13U 32 stroke
98 A2KJ 32 clickedObj
99 A3CQ 32 stroke
99 A3LT 32 clickedObj
100 AEF9 32 stroke
100 A17J 32 clickedObj
101 AALU 3 stroke
101 A3DY 2 clickedObj
102 A2MD 13 stroke
102 A31M 12 clickedObj
103 AXZB 32 stroke
103 A1GK 32 clickedObj
104 A1H5 32 stroke
104 A15O 32 clickedObj
105 A24N 13 stroke
105 AFQG 13 clickedObj
106 A2ZS 8 stroke
106 A1U3 8 clickedObj
107 A2GB 12 stroke
107 A3JG 12 clickedObj
108 A2SH 8 stroke
108 A2DF 8 clickedObj
109 A3IJ 9 stroke
109 A24L 8 clickedObj
110 A4T5 9 stroke
110 A1IQ 8 clickedObj
111 A1CY 6 stroke
111 A2DV 5 clickedObj
112 ALKQ 3 stroke
112 A3OE 2 clickedObj
113 A30J 32 stroke
113 A3W6 32 clickedObj
114 A2VW 32 stroke
114 A2OV 32 clickedObj
115 A101 32 stroke
115 AX17 32 clickedObj
116 A3HS 32 stroke
116 A11T 32 clickedObj
   ===========   
93 valid gameIDs (# complete games).

In [ ]:


In [ ]:


In [10]:
TrialNum = []
GameID = []
Condition = []
Target = []
Distractor1 = []
Distractor2 = []
Distractor3 = []
Outcome = []
Response = []
numStrokes = []
drawDuration = [] # in seconds
viewerRT = []
svgStringLength = [] # sum of svg string for whole sketch
svgStringLengthPerStroke = [] # svg string length per stroke
numCurvesPerSketch = [] # number of curve segments per sketch
numCurvesPerStroke = [] # mean number of curve segments per stroke
svgStringStd = [] # std of svg string length across strokes for this sketch
Outcome = []
Pose = []
Svg = []

these_gameids = unfiltered_gameids

for g in these_gameids:
    print 'Analyzing game: ', g

    X = coll.find({ '$and': [{'gameid': g}, {'eventType': 'clickedObj'}]}).sort('time')
    Y = coll.find({ '$and': [{'gameid': g}, {'eventType': 'stroke'}]}).sort('time')

    for t in X:
        targetname = t['intendedName']
        distractors = [t['object2Name'],t['object3Name'],t['object4Name']]
        full_list = [t['intendedName'],t['object2Name'],t['object3Name'],t['object4Name']] 
        y = coll.find({ '$and': [{'gameid': g}, {'eventType': 'stroke'}, {'trialNum': t['trialNum']}]}).sort('time')
        ns = y.count()
        numStrokes.append(ns)
        drawDuration.append((y.__getitem__(ns-1)['time'] - y.__getitem__(0)['time'])/1000) # in seconds  
        y = coll.find({ '$and': [{'gameid': g}, {'eventType': 'stroke'}, {'trialNum': t['trialNum']}]}).sort('time')        
        z = coll.find({ '$and': [{'gameid': g}, {'eventType': 'clickedObj'}, {'trialNum': t['trialNum']}]}).sort('time')
        viewerRT.append((z.__getitem__(0)['time'] - y.__getitem__(ns-1)['time'])/1000)
        ls = [len(_y['svgData']) for _y in y]
        svgStringLength.append(reduce(lambda x, y: x + y, ls))
        y = coll.find({ '$and': [{'gameid': g}, {'eventType': 'stroke'}, {'trialNum': t['trialNum']}]}).sort('time')
        num_curves = [len([m.start() for m in re.finditer('c', _y['svgData'])]) for _y in y]
        y = coll.find({ '$and': [{'gameid': g}, {'eventType': 'stroke'}, {'trialNum': t['trialNum']}]}).sort('time')        
        _svg = []
        for _y in y:
            _svg.append(_y['svgData'])
        Svg.append(_svg)
        numCurvesPerSketch.append(reduce(lambda x, y: x + y, num_curves))
        numCurvesPerStroke.append(reduce(lambda x, y: x + y, num_curves)/ns)
        svgStringLengthPerStroke.append(reduce(lambda x, y: x + y, ls)/ns)
        svgStringStd.append(np.std(ls))
        ### aggregate game metadata
        TrialNum.append(t['trialNum'])
        GameID.append(t['gameid'])        
        Target.append(targetname)
        Condition.append(t['condition'])
        Response.append(t['clickedName'])
        Outcome.append(t['correct'])
        Distractor1.append(distractors[0])
        Distractor2.append(distractors[1])
        Distractor3.append(distractors[2])
        Pose.append(t['pose'])


Analyzing game:  7004-6ff0964c-ff95-40f9-8696-d6a8931c94d5
Analyzing game:  6224-40ab6004-b7c1-4d1d-a308-a061099290fc
Analyzing game:  8690-8b4e0b59-f3f2-4e43-b4a0-66caff2a72e4
Analyzing game:  3230-d1aa5a54-b0ce-4d0d-be06-e49efb324a4b
Analyzing game:  6786-9c3169eb-962e-468b-8922-b99247975eb2
Analyzing game:  5708-fd15d921-aa1b-46e4-ad51-e0c743c2db0d
Analyzing game:  4099-cfa19d59-4f8b-4d34-bd3f-23a1e8c79e67
Analyzing game:  9229-923201c3-dd68-4362-8eec-77cb88a647c4
Analyzing game:  5331-d3bd334d-3d8c-400e-b3b2-44cd69623cb7
Analyzing game:  1593-3cebc49a-ef16-451d-a5a9-aad9b5ac4695
Analyzing game:  2323-a9c585ff-0096-4f9c-8be4-e202993c654f
Analyzing game:  8154-5d8b5091-2c29-4502-9719-1b295ff55c49
Analyzing game:  6592-d354ecd6-f421-4200-98e1-8d7c0ee48a43
Analyzing game:  9903-d6e6a9ff-a878-4bee-b2d5-26e2e239460a
Analyzing game:  5412-7dc95fb9-5b93-4d9a-bf13-7d349722b687
Analyzing game:  5650-cb4a9e85-a383-43f6-83e6-331e286811d1
Analyzing game:  3058-fb4fe740-d862-453b-a08f-44375a040165
Analyzing game:  0225-fd115f45-542e-4c76-9672-54e60295fc00
Analyzing game:  1752-fba5d4af-f103-4e3a-b100-d479bb0a2d11
Analyzing game:  6373-a60ef7ba-4340-4fc3-b549-bf974318f61d
Analyzing game:  4088-45a9d4bd-2ce2-4404-8743-5d9a30dc38e2
Analyzing game:  9451-6c7f6084-1fb9-47c6-a7c2-36a20f2951c5
Analyzing game:  1970-1377644d-0742-4343-ae91-737a5b0fbd1f
Analyzing game:  4409-c993cc06-d675-4acb-881f-b5377cf24d71
Analyzing game:  8196-ad38e7de-f882-4af8-8645-0934a9585321
Analyzing game:  0927-5d6c38c2-51c0-44b7-a26e-28ff79b4f377
Analyzing game:  7567-ce474df0-a84b-46aa-b23d-c238f8234641
Analyzing game:  8297-39d66207-4fb6-430c-8e2b-4f95213b6a55
Analyzing game:  6097-bd18a2a0-7f23-4304-890f-cb44cf334fe4
Analyzing game:  4471-2bd3bf63-be9f-4c2b-8cf2-a27d10269baa
Analyzing game:  3897-71f63429-f74c-42ea-a48e-f21b736affde
Analyzing game:  9840-46b175c7-8715-49fe-99a6-0dae8776ef1b
Analyzing game:  1610-56ada1db-89be-40bc-a0f2-61e9769b6987
Analyzing game:  9488-b896538b-6d64-46b2-b5ff-a4509fb4d9a0
Analyzing game:  8033-46b51efe-5b34-4a26-a7f0-a5d08708618a
Analyzing game:  3169-1a552a49-44e5-4a78-bed6-72a6aca82625
Analyzing game:  7584-c7bb6a5e-cd82-45fc-823a-ada7595a25c5
Analyzing game:  8621-ca1f4a87-da08-43dd-96fb-948482e4d94c
Analyzing game:  2121-a3dd33f4-82fc-4913-991c-1d372f6923f0
Analyzing game:  3257-2f4b83dc-a618-4194-a666-67e8a3f5539d
Analyzing game:  7285-f99d9991-de84-43cc-b359-e9de387ab0b5
Analyzing game:  1682-6ebee481-ec2e-4624-a5d2-2e74803e940d
Analyzing game:  3444-a337b178-b097-4a79-bbf3-e7e2225bac12
Analyzing game:  3572-0843efc9-9dec-40f1-879f-2a61d8a3622d
Analyzing game:  0075-ad14e50c-f328-451b-82b0-2a7d3b392127
Analyzing game:  1227-b0df7616-c762-4bb6-8c0e-fcb7cf68ddba
Analyzing game:  3741-3d676fa8-13ae-4785-8a62-7cc820eaccb0
Analyzing game:  4546-1d43f895-aec3-43e5-83dd-8069d67a2b47
Analyzing game:  5325-5c1c06e3-3674-4ae6-add2-d188a9a7c4b5
Analyzing game:  8486-a0a44a5f-4eb9-4924-b2b6-247478e1ce8d
Analyzing game:  8901-cec404f6-c1b9-458f-8ab5-3fac34c1563f
Analyzing game:  6698-4fc0cc09-7c7a-4adf-95d7-af88c375d43a
Analyzing game:  0647-bfcd78e5-085c-4631-a47c-0f3dadf71345
Analyzing game:  1695-dcc9fa2e-386a-42cc-a4cb-fbb1a309c5d9
Analyzing game:  2829-820b338d-5720-4964-bd22-8ba38329569d
Analyzing game:  6500-391008be-12c2-4a97-a943-7bf13a56bbb7
Analyzing game:  2475-56c56a85-8926-4355-b02d-9fe236623033
Analyzing game:  5707-49e9e7c8-5fe1-4469-9905-4ba89ccde7dd
----------------------------------------------------------------
AutoReconnect                  Traceback (most recent call last)
<ipython-input-10-6b6cad5c05cf> in <module>()
     39         z = coll.find({ '$and': [{'gameid': g}, {'eventType': 'clickedObj'}, {'trialNum': t['trialNum']}]}).sort('time')
     40         viewerRT.append((z.__getitem__(0)['time'] - y.__getitem__(ns-1)['time'])/1000)
---> 41         ls = [len(_y['svgData']) for _y in y]
     42         svgStringLength.append(reduce(lambda x, y: x + y, ls))
     43         y = coll.find({ '$and': [{'gameid': g}, {'eventType': 'stroke'}, {'trialNum': t['trialNum']}]}).sort('time')

/Users/judithfan/Library/Python/2.7/lib/python/site-packages/pymongo/cursor.pyc in next(self)
   1130         if self.__empty:
   1131             raise StopIteration
-> 1132         if len(self.__data) or self._refresh():
   1133             if self.__manipulate:
   1134                 _db = self.__collection.database

/Users/judithfan/Library/Python/2.7/lib/python/site-packages/pymongo/cursor.pyc in _refresh(self)
   1053                                        self.__batch_size,
   1054                                        self.__read_concern,
-> 1055                                        self.__collation))
   1056             if not self.__id:
   1057                 self.__killed = True

/Users/judithfan/Library/Python/2.7/lib/python/site-packages/pymongo/cursor.pyc in __send_message(self, operation)
    890             try:
    891                 response = client._send_message_with_response(operation,
--> 892                                                               **kwargs)
    893                 self.__address = response.address
    894                 if self.__exhaust:

/Users/judithfan/Library/Python/2.7/lib/python/site-packages/pymongo/mongo_client.pyc in _send_message_with_response(self, operation, read_preference, exhaust, address)
    948             self.__all_credentials,
    949             self._event_listeners,
--> 950             exhaust)
    951 
    952     def _reset_on_error(self, server, func, *args, **kwargs):

/Users/judithfan/Library/Python/2.7/lib/python/site-packages/pymongo/mongo_client.pyc in _reset_on_error(self, server, func, *args, **kwargs)
    959         """
    960         try:
--> 961             return func(*args, **kwargs)
    962         except NetworkTimeout:
    963             # The socket has been closed. Don't reset the server.

/Users/judithfan/Library/Python/2.7/lib/python/site-packages/pymongo/server.pyc in send_message_with_response(self, operation, set_slave_okay, all_credentials, listeners, exhaust)
    134             try:
    135                 sock_info.send_message(data, max_doc_size)
--> 136                 response_data = sock_info.receive_message(1, request_id)
    137             except Exception as exc:
    138                 if publish:

/Users/judithfan/Library/Python/2.7/lib/python/site-packages/pymongo/pool.pyc in receive_message(self, operation, request_id)
    508                 self.sock, operation, request_id, self.max_message_size)
    509         except BaseException as error:
--> 510             self._raise_connection_failure(error)
    511 
    512     def legacy_write(self, request_id, msg, max_doc_size, with_last_error):

/Users/judithfan/Library/Python/2.7/lib/python/site-packages/pymongo/pool.pyc in _raise_connection_failure(self, error)
    608             _raise_connection_failure(self.address, error)
    609         else:
--> 610             raise error
    611 
    612     def __eq__(self, other):

AutoReconnect: connection closed

In [ ]:
## compose pandas dataframe from lists
iteration = ['pilot2']*len(GameID)

_D = pd.DataFrame([GameID,TrialNum,Condition, Target, drawDuration, Outcome, Response, numStrokes, \
                  svgStringLength, svgStringLengthPerStroke, svgStringStd, Distractor1, Distractor2, \
                   Distractor3, Pose, iteration, Svg, viewerRT]) \

D =_D.transpose()
D.columns = ['gameID','trialNum','condition', 'target', 'drawDuration','outcome', 'response', \
             'numStrokes', 'svgStringLength', 'svgStringLengthPerStroke', 'svgStringStd', \
            'Distractor1', 'Distractor2', 'Distractor3', 'pose', 'iteration', 'svg','viewerRT']

In [ ]:


In [ ]:
## add png to D dataframe
png = []
for g in these_gameids:
    X = coll.find({ '$and': [{'gameid': g}, {'eventType': 'clickedObj'}]}).sort('time')
    Y = coll.find({ '$and': [{'gameid': g}, {'eventType': 'stroke'}]}).sort('time')
    # print out sketches from all trials from this game
    for t in X: 
        png.append(t['pngString'])
D = D.assign(png=pd.Series(png).values)

iteration = ['pilot2']*len(D['gameID'].values)
D = D.assign(iteration=pd.Series(iteration).values)

## add another cost-related dependent measure: mean pixel intensity (amount of ink spilled) -- to handle
## some weird glitches in the num stroke count
mean_intensity = []
imsize = 100
numpix = imsize**2
thresh = 250

for i,_d in D.iterrows():
    imgData = _d['png']
    filestr = base64.b64decode(imgData)
    fname = os.path.join('sketch.png')
    with open(fname, "wb") as fh:
        fh.write(imgData.decode('base64'))
    im = Image.open(fname).resize((imsize,imsize))
    _im = np.array(im)
    mean_intensity.append(len(np.where(_im[:,:,3].flatten()>thresh)[0])/numpix)
    
# add mean_intensity to the main D dataframe 
### btw: mean_intensity and numStrokes is about 0.43 spearman correlated.
D = D.assign(mean_intensity=pd.Series(mean_intensity).values)
print stats.spearmanr(D['mean_intensity'].values,D['numStrokes'].values)

category = [h.objcat[t] for t in D.target.values]
D = D.assign(category=pd.Series(category).values)

In [ ]:
# save D out as group_data.csv 
if len(np.unique(D.gameID.values))==len(valid_gameids):
    D.to_csv(os.path.join(analysis_dir,'sketchpad_basic_pilot2_group_data.csv'))
    print 'Saving out valid games csv'
elif len(np.unique(D.gameID.values))==len(unfiltered_gameids):
    D.to_csv(os.path.join(analysis_dir,'sketchpad_basic_pilot2_group_data_unfiltered.csv'))
    print 'Saving out unfiltered games csv'

In [ ]:


In [ ]:


In [ ]:


In [ ]:

Visualize summary stats


In [7]:
# read group data csv in as D
D = pd.read_csv(os.path.join(analysis_dir,'sketchpad_basic_pilot2_group_data.csv'))

In [70]:


In [78]:
def get_mean_by_condition_and_game(D,var='numStrokes'):
    '''
    Input: dataframe D and name of variable of interest (which is a column of D)
    Output: two vectors, one for close and one for far condition,
            with mean for each game
    '''
    
    d = D.groupby(['gameID','condition'])[var].mean().reset_index()
    far_d = d[d['condition']=='further'][var].values
    close_d = d[d['condition']=='closer'][var].values
    return far_d, close_d

further_strokes, closer_strokes = get_mean_by_condition_and_game(D, var='numStrokes')
further_drawDuration, closer_drawDuration = get_mean_by_condition_and_game(D, var='drawDuration')
further_meanintensity, closer_meanintensity = get_mean_by_condition_and_game(D, var='mean_intensity')
further_accuracy, closer_accuracy = get_mean_by_condition_and_game(D, var='outcome')
further_viewerRT, closer_viewerRT = get_mean_by_condition_and_game(D, var='viewerRT')

In [79]:


In [75]:


In [ ]:


In [ ]:


In [61]:
def trim_outliers(x):
    mu = np.mean(x)
    sd = np.std(x)
    thresh = mu + sd*3
    y = [i for i in x if i<thresh]
    return y

def bootstrap(w,nIter=10000):
    boot = []
    for i in np.arange(nIter):
        boot.append(np.mean(np.random.RandomState(i).choice(w,len(w),replace=True)))
    boot = np.array(boot) 
    p1 = sum(boot<0)/len(boot) * 2
    p2 = sum(boot>0)/len(boot) * 2
    p = np.min([p1,p2])        
    lb = np.percentile(boot,2.5)
    ub = np.percentile(boot,97.5)
    print 'p = {}'.format(p) 
    return boot, p, lb, ub

print D.groupby('condition')['numStrokes'].mean()
print D.groupby('condition')['mean_intensity'].mean()
print D.groupby('condition')['drawDuration'].mean()
print D.groupby('condition')['outcome'].mean()
print D.groupby('condition')['viewerRT'].mean()


condition
closer     13.538306
further     8.077285
Name: numStrokes, dtype: float64
condition
closer     0.053560
further    0.041718
Name: mean_intensity, dtype: float64
condition
closer     30.647843
further    13.873610
Name: drawDuration, dtype: float64
condition
closer     0.879032
further    0.996640
Name: outcome, dtype: float64
condition
closer     8.320626
further    6.319662
Name: viewerRT, dtype: float64

In [38]:
sns.set_context('talk')
plt.figure(figsize=(12,4))
plt.subplot(1,5,1)
ax = sns.barplot(data=D,x='condition',y='numStrokes')
plt.ylabel('num strokes')
plt.ylim(0,16)
plt.subplot(1,5,2)
sns.barplot(data=D,x='condition',y='mean_intensity')
plt.ylabel('mean pixel intensity')
plt.ylim(0,0.06)
plt.subplot(1,5,3)
sns.barplot(data=D,x='condition',y='outcome')
plt.ylabel('accuracy')
plt.ylim([0,1.01])
plt.subplot(1,5,4)
sns.barplot(data=D,x='condition',y='drawDuration')
plt.ylabel('draw duration (s)')
plt.ylim(0,35)
plt.subplot(1,5,5)
ax = sns.barplot(data=D,x='condition',y='viewerRT')
plt.ylabel('viewer RT (s)')
plt.ylim(0,10)
plt.tight_layout()
if not os.path.exists('./plots'):
    os.makedirs('./plots')
plt.savefig('./plots/sketchpad_basic_pilot2_taskperformance.pdf')
plt.savefig('../manuscript/figures/raw/sketchpad_basic_taskperformance.pdf')



In [39]:
overall_accuracy = np.mean(D['outcome'].values)
print 'Overall accuracy (collapsing across conditions) = {}'.format(np.round(overall_accuracy,3))

accuracy_by_game = D.groupby('gameID')['outcome'].mean()
boot, p, lb, ub = bootstrap(accuracy_by_game)
print '95% CI for accuracy across games: ({}, {}), p = {}'.format(np.round(lb,3),np.round(ub,3),p)


Overall accuracy (collapsing across conditions) = 0.938
p = 2.0
95% CI for accuracy across games: (0.927, 0.949), p = 0.0

In [64]:
ACG = D.groupby(['gameID','condition'])['outcome'].mean().reset_index()
grouped = ACG.groupby('condition')['outcome']
for name,group in grouped:
    boot, p, lb, ub = bootstrap(group)
    print '95% CI for accuracy for {} condition: [{}, {}], p = {}'.format(name,np.round(lb,3),np.round(ub,3),p)


p = 0.0
95% CI for accuracy for closer condition: [0.858, 0.899], p = 0.0
p = 0.0
95% CI for accuracy for further condition: [0.993, 0.999], p = 0.0

In [ ]:


In [40]:
## bootstrapped CI's on main task performance measures
boot, p, lb, ub = bootstrap(closer_strokes)
print '95% CI for closer strokes: ({}, {})'.format(np.round(lb,3),np.round(ub,3))

boot, p, lb, ub = bootstrap(further_strokes)
print '95% CI for further strokes: ({}, {})'.format(np.round(lb,3),np.round(ub,3))


p = 2.0
95% CI for closer strokes: (10.589, 17.981)
p = 2.0
95% CI for further strokes: (6.591, 10.64)

In [ ]:


In [41]:
## bootstrapped CI's on main task performance measures
boot, p, lb, ub = bootstrap(further_strokes - closer_strokes)
print '95% CI for closer vs. further strokes: [{}, {}], p = {}'.format(np.round(lb,3),np.round(ub,3),p)

boot, p, lb, ub = bootstrap(further_meanintensity - closer_meanintensity)
print '95% CI for closer vs. further mean intensity: [{}, {}], p = {}'.format(np.round(lb,3),np.round(ub,3),p)

boot, p, lb, ub = bootstrap(further_drawDuration - closer_drawDuration)
print '95% CI for closer vs. further draw duration: [{}, {}], p = {}'.format(np.round(lb,3),np.round(ub,3),p)

boot, p, lb, ub = bootstrap(further_viewerRT - closer_viewerRT)
print '95% CI for closer vs. further viewer RT: [{}, {}], p = {}'.format(np.round(lb,3),np.round(ub,3),p)


p = 0.0
95% CI for closer vs. further strokes: [-7.815, -3.73], p = 2.0
p = 0.0
95% CI for closer vs. further mean intensity: [-0.014, -0.01], p = 2.0
p = 0.0
95% CI for closer vs. further draw duration: [-18.682, -14.856], p = 2.0
p = 0.0
95% CI for closer vs. further viewer RT: [-2.739, -1.257], p = 2.0

In [ ]:


In [ ]:


In [ ]:
fig = plt.figure(figsize=(10,10))
plt.subplot(2,2,1)
lb = 0
ub = 24
plt.plot([lb,ub],[lb,ub],'k--')
plt.scatter(closer_strokes,further_strokes,64,(0.8,0.4,0.4))
plt.xlim([lb,ub])
plt.ylim([lb,ub])
plt.title('number of strokes')
plt.xlabel('closer')
plt.ylabel('further')
plt.subplot(2,2,2)
lb = 0
ub = 3000
plt.plot([lb,ub],[lb,ub],'k--')
plt.scatter(closer_svgLength,further_svgLength,64,(0.8,0.4,0.4))
plt.xlim([lb,ub])
plt.ylim([lb,ub])
plt.tight_layout()
plt.title('svg string length')
plt.xlabel('closer')
plt.ylabel('further')
plt.subplot(2,2,3)
lb = 0
ub = 300
plt.plot([lb,ub],[lb,ub],'k--')
plt.scatter(closer_svgStd,further_svgStd,64,(0.8,0.4,0.4))
plt.xlim([lb,ub])
plt.ylim([lb,ub])
plt.title('stroke variability')
plt.xlabel('closer')
plt.ylabel('further')
plt.subplot(2,2,4)
lb = 0
ub = 300
plt.plot([lb,ub],[lb,ub],'k--')
plt.scatter(closer_svgLengthPS,further_svgLengthPS,64,(0.8,0.4,0.4))
plt.xlim([lb,ub])
plt.ylim([lb,ub])
plt.tight_layout()
plt.title('svg length per stroke')
plt.xlabel('closer')
plt.ylabel('further')
save_out = 1
if not os.path.exists('plots'):
    os.makedirs('plots')
if save_out:
    save('plots/svg_summary_scatter_{}'.format(iterationName), ext='pdf', close=False, verbose=True)

In [ ]:
fig = plt.figure(figsize=(8,4))
lb = 0
ub = 1.03
plt.subplot(1,2,1)
plt.plot([lb,ub],[lb,ub],'k--')
plt.scatter(closer_accuracy,further_accuracy,64,(0.8,0.4,0.4))
plt.xlim([lb,ub])
plt.ylim([lb,ub])
plt.title('accuracy')
plt.xlabel('closer')
plt.ylabel('further')
plt.subplot(1,2,2)
lb = 0
ub = 36
plt.plot([lb,ub],[lb,ub],'k--')
plt.scatter(closer_drawDuration,further_drawDuration,64,(0.75,0.3,0.2))
plt.xlim([lb,ub])
plt.ylim([lb,ub])
plt.title('draw duration')
plt.xlabel('closer')
plt.ylabel('further')
plt.tight_layout()
save_out = 1
if save_out:
    save('plots/performance_summary_scatter_{}'.format(iterationName), ext='pdf', close=False, verbose=True)

In [134]:
def get_canonical(category):    
    stimFile = os.path.join(exp_dir,'stimList_subord.js')
    with open(stimFile) as f:
        stimList = json.load(f)    
    allviews = [i['filename'] for i in stimList if i['basic']==category]
    canonical = [a for a in allviews if a[-8:]=='0035.png']    
    return canonical

def get_actual_pose(subordinate,pose):
    stimFile = os.path.join(exp_dir,'stimList_subord.js')
    with open(stimFile) as f:
        stimList = json.load(f)
    inpose = [i['filename'] for i in stimList if (i['subordinate']==subordinate) and (i['pose']==pose)]
    return inpose
    
def get_subord_names(category):
    full_names = get_canonical(category)    
    return [c.split('_')[2] for c in full_names]

def get_basic_names(subordinate):
    stimFile = os.path.join(exp_dir,'stimList_subord.js')
    with open(stimFile) as f:
        stimList = json.load(f)   
    allviews = [i['filename'] for i in stimList if i['subordinate']==subordinate]
    canonical = [a for a in allviews if a[-8:]=='0035.png']      
    return canonical[0].split('_')[0]

def build_url_from_category(category):
    full_names = get_canonical(category)
    url_prefix = 'https://s3.amazonaws.com/sketchloop-images-subord/'
    urls = []
    for f in full_names:
        urls.append(url_prefix + f)
    return urls

def build_url_from_filenames(filenames):
    url_prefix = 'https://s3.amazonaws.com/sketchloop-images-subord/'
    urls = []
    for f in filenames:
        urls.append(url_prefix + f)
    return urls

def plot_from_url(URL):
    file = cStringIO.StringIO(urllib.urlopen(URL).read())
    img = Image.open(file)    

def plot_gallery(category):
    import matplotlib.pyplot as plt
    import matplotlib.gridspec as gridspec

    plt.figure(figsize = (8,8))
    gs1 = gridspec.GridSpec(8, 8)
    gs1.update(wspace=0.025, hspace=0.05)

    url_prefix = 'https://s3.amazonaws.com/sketchloop-images-subord/'
    for (i,c) in enumerate(category):
        URL = url_prefix + c
        file = cStringIO.StringIO(urllib.urlopen(URL).read())
        img = Image.open(file)
        p = plt.subplot(3,3,i+1)
        plt.imshow(img)
        p.get_xaxis().set_ticklabels([])
        p.get_yaxis().set_ticklabels([])
        p.get_xaxis().set_ticks([])
        p.get_yaxis().set_ticks([])
        p.set_aspect('equal')
        subord = c.split('_')[2]
        plt.title(subord)
    plt.tight_layout()

In [ ]:


In [ ]:
## print out sketches with target & distractors from this game
import traceback
backup_path_images = '/Users/judithfan/Dropbox/stimuli_repository/subordinate_allrotations_6_minified'

_valid_gameids = valid_gameids[:3]

## get list of all incorrect sketch path names
incorrect_trial_paths = []

run_this = 0
if run_this:
#     all_games = click_files
    for g in valid_gameids:
        print 'Printing out sketches from game: ' + g
        _D = D[(D.gameID==g)]
        _D = _D.sort_values(by=['target'])
        _i = 1
        textsize=12
        fig = plt.figure(figsize=(16,6))        
        for i,_d in _D.iterrows():
            imgData = _d['png']
            filestr = base64.b64decode(imgData)
            target_sketch_dir = os.path.join(analysis_dir,'sketches_pilot2','sketch')
            if not os.path.exists(target_sketch_dir):
                os.makedirs(target_sketch_dir)
            fname = os.path.join(target_sketch_dir,'gameID_' + _d['gameID'] + '_trial_' + str(_d['trialNum']) + '.png')
            with open(fname, "wb") as fh:
                fh.write(imgData.decode('base64'))
            textsize = 16
            # first plot the target
            im = Image.open(fname)
            p = plt.subplot(2,4,1)
            plt.imshow(im)
            sns.set_style('white')
            k = p.get_xaxis().set_ticklabels([])
            k = p.get_yaxis().set_ticklabels([])
            k = p.get_xaxis().set_ticks([])
            k = p.get_yaxis().set_ticks([])        
            targetname = _d['target']
            distractors = [_d['Distractor1'],_d['Distractor2'],_d['Distractor3']]
            full_list = [_d['target'],_d['Distractor1'],_d['Distractor2'],_d['Distractor3']] 
            outcome = _d['outcome']
            if _d['outcome']==0:
                incorrect_trial_paths.append('gameID_' + _d['gameID'] + '_trial_' + str(_d['trialNum']) + '_' + _d['target'] + '.png')            
                        
            response = _d['response']        
            if outcome == 1:
                sides = ['bottom','top','right','left']
                for s in sides:
                    p.spines[s].set_color((0.4,0.8,0.4))
                    p.spines[s].set_linewidth(4)                               
            else:
                sides = ['bottom','top','right','left']
                for s in sides:
                    p.spines[s].set_color((0.9,0.2,0.2))
                    p.spines[s].set_linewidth(4)                      
            plt.title(targetname,fontsize=textsize)
            plt.ylabel('v:' + response,fontsize=textsize-2)        
        
            # fig = plt.figure(figsize=(8,3))
            for (i,d) in enumerate(full_list):
                if os.path.exists(backup_path_images):
                    if hasattr(t, 'pose'):
                        fn = os.path.join(backup_path_images,get_actual_pose(d,pose)[0])
                    else:
                        fn = os.path.join(backup_path_images,get_actual_pose(d,35)[0])
                else:
                    if hasattr(t, 'pose'):
                        pose = t['pose']
                        URL = build_url_from_filenames(get_actual_pose(d,pose)[0])
                    else:
                        URL = full_dict[d]
                    fn = cStringIO.StringIO(urllib.urlopen(URL).read())
                img = Image.open(fn)
                p = plt.subplot(2,4,i+5)
                plt.imshow(img)
                p.get_xaxis().set_ticklabels([])
                p.get_yaxis().set_ticklabels([])
                p.get_xaxis().set_ticks([])
                p.get_yaxis().set_ticks([])
                p.set_aspect('equal')   
                plt.title(d)

            sketch_dir = os.path.join(analysis_dir,'sketches_pilot2','full_display')
            if not os.path.exists(sketch_dir):
                os.makedirs(os.path.join(analysis_dir,'sketches_pilot2','full_display'))
            filepath = os.path.join(sketch_dir,'gameID_' + _d['gameID'] + '_trial_' + str(_d['trialNum']))
            save(filepath, ext='png', close=True, verbose=False)

In [ ]:
## save out number of incorrect trial paths
print "Number of incorrect trial paths: {}".format(str(len(incorrect_trial_paths)))
with open('incorrect_trial_paths_pilot2.txt', 'w') as f:
    for path in incorrect_trial_paths:
        f.write(path + '\n')

In [ ]:


In [137]:
## print out sketches with target & distractors from this game in separate folders
import traceback
backup_path_images = '/Users/judithfan/Dropbox/stimuli_repository/subordinate_allrotations_6_minified'

# _valid_gameids = valid_gameids[:3]

target_sketch_dir = os.path.join(analysis_dir,'sketches_pilot2','sketch')
target_3D_dir = os.path.join(analysis_dir,'sketches_pilot2','target')
distractor1_3D_dir = os.path.join(analysis_dir,'sketches_pilot2','distractor1')
distractor2_3D_dir = os.path.join(analysis_dir,'sketches_pilot2','distractor2')
distractor3_3D_dir = os.path.join(analysis_dir,'sketches_pilot2','distractor3')
out_paths = [target_3D_dir,distractor1_3D_dir,distractor2_3D_dir,distractor3_3D_dir]


if not os.path.exists(target_3D_dir):
    os.makedirs(os.path.join(analysis_dir,'sketches_pilot2','target'))
    os.makedirs(os.path.join(analysis_dir,'sketches_pilot2','distractor1'))
    os.makedirs(os.path.join(analysis_dir,'sketches_pilot2','distractor2'))
    os.makedirs(os.path.join(analysis_dir,'sketches_pilot2','distractor3'))
    os.makedirs(os.path.join(analysis_dir,'sketches_pilot2','sketch'))    

run_this = 1
if run_this:
    for g in valid_gameids:
        print 'Printing out sketches from game: ' + g
        _D = D[(D.gameID==g)]
        _D = _D.sort_values(by=['target'])
        _i = 1
        textsize=12
        fig = plt.figure(figsize=(16,6))        
        for i,_d in _D.iterrows():
            imgData = _d['png']
            filestr = base64.b64decode(imgData)
            if not os.path.exists(target_sketch_dir):
                os.makedirs(target_sketch_dir)
            fname = os.path.join(target_sketch_dir,'gameID_' + _d['gameID'] + '_trial_' + str(_d['trialNum']) + '_' + _d['target'] + '_' + _d['condition'] + '.png')
            with open(fname, "wb") as fh:
                fh.write(imgData.decode('base64'))
            im = Image.open(fname)
            im.save(fname)

#             targetname = _d['target']
#             distractors = [_d['Distractor1'],_d['Distractor2'],_d['Distractor3']]
#             full_list = [_d['target'],_d['Distractor1'],_d['Distractor2'],_d['Distractor3']]         
            
#             for (i,d) in enumerate(full_list):
#                 if os.path.exists(backup_path_images):
#                     if hasattr(_d, 'pose'):
#                         fn = os.path.join(backup_path_images,get_actual_pose(d,pose)[0])
#                     else:
#                         fn = os.path.join(backup_path_images,get_actual_pose(d,35)[0])
#                 else:
#                     if hasattr(_d, 'pose'):
#                         pose = _d['pose']
#                         URL = build_url_from_filenames(get_actual_pose(d,pose)[0])
#                     else:
#                         URL = full_dict[d]
#                     fn = cStringIO.StringIO(urllib.urlopen(URL).read())
#                 fig = plt.figure(figsize=(8,8))                    
#                 im = Image.open(fn)
#                 im = im.resize((256,256), Image.ANTIALIAS).convert('RGB')                                
#                 out_dirs = [target_3D_dir,distractor1_3D_dir,distractor2_3D_dir,distractor3_3D_dir]                
#                 out_path = os.path.join(out_dirs[i],'gameID_' + _d['gameID'] + '_trial_' + str(_d['trialNum']) + '_' + d + '.png')
#                 im.save(out_path)


Printing out sketches from game: 7004-6ff0964c-ff95-40f9-8696-d6a8931c94d5
Printing out sketches from game: 6224-40ab6004-b7c1-4d1d-a308-a061099290fc
Printing out sketches from game: 8690-8b4e0b59-f3f2-4e43-b4a0-66caff2a72e4
Printing out sketches from game: 3230-d1aa5a54-b0ce-4d0d-be06-e49efb324a4b
Printing out sketches from game: 6786-9c3169eb-962e-468b-8922-b99247975eb2
Printing out sketches from game: 5708-fd15d921-aa1b-46e4-ad51-e0c743c2db0d
Printing out sketches from game: 4099-cfa19d59-4f8b-4d34-bd3f-23a1e8c79e67
Printing out sketches from game: 9229-923201c3-dd68-4362-8eec-77cb88a647c4
Printing out sketches from game: 5331-d3bd334d-3d8c-400e-b3b2-44cd69623cb7
Printing out sketches from game: 1593-3cebc49a-ef16-451d-a5a9-aad9b5ac4695
Printing out sketches from game: 2323-a9c585ff-0096-4f9c-8be4-e202993c654f
Printing out sketches from game: 8154-5d8b5091-2c29-4502-9719-1b295ff55c49
Printing out sketches from game: 6592-d354ecd6-f421-4200-98e1-8d7c0ee48a43
Printing out sketches from game: 9903-d6e6a9ff-a878-4bee-b2d5-26e2e239460a
Printing out sketches from game: 5412-7dc95fb9-5b93-4d9a-bf13-7d349722b687
Printing out sketches from game: 5650-cb4a9e85-a383-43f6-83e6-331e286811d1
Printing out sketches from game: 3058-fb4fe740-d862-453b-a08f-44375a040165
Printing out sketches from game: 0225-fd115f45-542e-4c76-9672-54e60295fc00
Printing out sketches from game: 1752-fba5d4af-f103-4e3a-b100-d479bb0a2d11
Printing out sketches from game: 6373-a60ef7ba-4340-4fc3-b549-bf974318f61d
Printing out sketches from game: 4088-45a9d4bd-2ce2-4404-8743-5d9a30dc38e2
/Users/judithfan/Library/Python/2.7/lib/python/site-packages/matplotlib/pyplot.py:528: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
  max_open_warning, RuntimeWarning)
Printing out sketches from game: 9451-6c7f6084-1fb9-47c6-a7c2-36a20f2951c5
Printing out sketches from game: 1970-1377644d-0742-4343-ae91-737a5b0fbd1f
Printing out sketches from game: 4409-c993cc06-d675-4acb-881f-b5377cf24d71
Printing out sketches from game: 8196-ad38e7de-f882-4af8-8645-0934a9585321
Printing out sketches from game: 0927-5d6c38c2-51c0-44b7-a26e-28ff79b4f377
Printing out sketches from game: 7567-ce474df0-a84b-46aa-b23d-c238f8234641
Printing out sketches from game: 8297-39d66207-4fb6-430c-8e2b-4f95213b6a55
Printing out sketches from game: 6097-bd18a2a0-7f23-4304-890f-cb44cf334fe4
Printing out sketches from game: 4471-2bd3bf63-be9f-4c2b-8cf2-a27d10269baa
Printing out sketches from game: 3897-71f63429-f74c-42ea-a48e-f21b736affde
Printing out sketches from game: 9840-46b175c7-8715-49fe-99a6-0dae8776ef1b
Printing out sketches from game: 1610-56ada1db-89be-40bc-a0f2-61e9769b6987
Printing out sketches from game: 9488-b896538b-6d64-46b2-b5ff-a4509fb4d9a0
Printing out sketches from game: 8033-46b51efe-5b34-4a26-a7f0-a5d08708618a
Printing out sketches from game: 3169-1a552a49-44e5-4a78-bed6-72a6aca82625
Printing out sketches from game: 7584-c7bb6a5e-cd82-45fc-823a-ada7595a25c5
Printing out sketches from game: 8621-ca1f4a87-da08-43dd-96fb-948482e4d94c
Printing out sketches from game: 2121-a3dd33f4-82fc-4913-991c-1d372f6923f0
Printing out sketches from game: 3257-2f4b83dc-a618-4194-a666-67e8a3f5539d
Printing out sketches from game: 7285-f99d9991-de84-43cc-b359-e9de387ab0b5
Printing out sketches from game: 1682-6ebee481-ec2e-4624-a5d2-2e74803e940d
Printing out sketches from game: 3444-a337b178-b097-4a79-bbf3-e7e2225bac12
Printing out sketches from game: 3572-0843efc9-9dec-40f1-879f-2a61d8a3622d
Printing out sketches from game: 0075-ad14e50c-f328-451b-82b0-2a7d3b392127
Printing out sketches from game: 1227-b0df7616-c762-4bb6-8c0e-fcb7cf68ddba
Printing out sketches from game: 3741-3d676fa8-13ae-4785-8a62-7cc820eaccb0
Printing out sketches from game: 4546-1d43f895-aec3-43e5-83dd-8069d67a2b47
Printing out sketches from game: 5325-5c1c06e3-3674-4ae6-add2-d188a9a7c4b5
Printing out sketches from game: 8486-a0a44a5f-4eb9-4924-b2b6-247478e1ce8d
Printing out sketches from game: 8901-cec404f6-c1b9-458f-8ab5-3fac34c1563f
Printing out sketches from game: 6698-4fc0cc09-7c7a-4adf-95d7-af88c375d43a
Printing out sketches from game: 0647-bfcd78e5-085c-4631-a47c-0f3dadf71345
Printing out sketches from game: 1695-dcc9fa2e-386a-42cc-a4cb-fbb1a309c5d9
Printing out sketches from game: 6500-391008be-12c2-4a97-a943-7bf13a56bbb7
Printing out sketches from game: 2475-56c56a85-8926-4355-b02d-9fe236623033
Printing out sketches from game: 5707-49e9e7c8-5fe1-4469-9905-4ba89ccde7dd
Printing out sketches from game: 2721-f28245be-a3ac-425e-9538-5c0803980807
Printing out sketches from game: 2611-14794729-06be-4093-aac5-8a631b1fa894
Printing out sketches from game: 5401-eaf89cb8-eaee-4824-949a-f6a80bd05fc3
Printing out sketches from game: 4922-1aed9a2a-2e30-4032-9087-500ec1c2d3aa
Printing out sketches from game: 2111-7c2c9b7b-6c0b-43e7-b3a9-c9edf26da2a1
Printing out sketches from game: 4613-4fa2802d-8f43-4ffd-9a0a-9d29240651d1
Printing out sketches from game: 3113-105e6653-7fd1-4451-af00-46bb3145880a
Printing out sketches from game: 7988-85f09ac5-8225-48f3-9367-e890cdbb4ffb
Printing out sketches from game: 6486-e7055f99-5fec-4fb7-a7fd-7ebf49ba594f
Printing out sketches from game: 0773-7fd737ec-3498-4e32-b097-7d7f0b9a0af8
Printing out sketches from game: 0303-238b7c04-aff2-417c-b7ab-895bcb3d54b9
Printing out sketches from game: 2137-5eb24312-af96-43dc-bb4b-76ac0d817ede
Printing out sketches from game: 5148-2dd2d418-6ff6-40f1-ac59-e201d15bc528
Printing out sketches from game: 9699-54dcccb8-23c7-45a9-8a18-f3a9ac597eb6
Printing out sketches from game: 2107-760dc7ba-9d69-4d14-89ce-16d8e4ed049d
Printing out sketches from game: 1649-32db6539-aa0f-4f13-85ad-e1082911fc9f
Printing out sketches from game: 8844-b38e583e-3f9a-4f4e-baa2-1ad91742f7d4
Printing out sketches from game: 8265-92081336-152b-4a90-bdb4-fea038f4c9b8
Printing out sketches from game: 2769-b075d070-88e5-47fe-b275-c49134b19ceb
Printing out sketches from game: 7639-4967af0b-721a-46b1-a2ca-3010355ac1f0
Printing out sketches from game: 3485-477008c1-e529-4ad0-a62b-df33c782a5e3
Printing out sketches from game: 6444-67a3b4d4-43a4-41bb-a9cf-e8739fbe8802
Printing out sketches from game: 8484-f49ea84f-5e54-4a64-b793-bed95e9aa1fd
Printing out sketches from game: 6311-cd21a68a-f1df-4290-b744-b0c7c7c60ed8
Printing out sketches from game: 0834-74e58d84-5f2f-4ffd-8df3-e32076ea5aa1
Printing out sketches from game: 2216-946e1652-c7ea-4dc7-8829-129c7cc55176
Printing out sketches from game: 5994-c7c61529-a835-4433-9c73-f628a189f385
Printing out sketches from game: 7823-f830a2ad-96de-4d1f-a926-5b44d0a625aa
Printing out sketches from game: 1783-0c833753-f18a-428d-9d3a-2e37d06f04e6
Printing out sketches from game: 7106-d5bbcf75-2894-4656-b1bd-19e73abf8a17
Printing out sketches from game: 7311-9dac6fad-97de-467c-932a-e02645c5c647
Printing out sketches from game: 0152-6051cc20-5fbc-43f5-8ca3-08711b390cfc
Printing out sketches from game: 4609-852cfd4d-44d8-42fc-9c7c-8460ce918f16
Printing out sketches from game: 3956-be947e80-531d-42ce-b238-e0b3bd997edf
Printing out sketches from game: 1233-33433bd3-d72b-4c2a-9ed0-3e83a80f8e94
Printing out sketches from game: 9877-e1c91119-da46-40fa-82fe-17405ca56a3b
<matplotlib.figure.Figure at 0x11030a550>
<matplotlib.figure.Figure at 0x1102f7d90>
<matplotlib.figure.Figure at 0x11030aa50>
<matplotlib.figure.Figure at 0x11030a350>
<matplotlib.figure.Figure at 0x10e60ef90>
<matplotlib.figure.Figure at 0x11030a290>
<matplotlib.figure.Figure at 0x1101fb390>
<matplotlib.figure.Figure at 0x109453310>
<matplotlib.figure.Figure at 0x10e6098d0>
<matplotlib.figure.Figure at 0x10f207410>
<matplotlib.figure.Figure at 0x10e4c1e90>
<matplotlib.figure.Figure at 0x10f2072d0>
<matplotlib.figure.Figure at 0x10e4c1350>
<matplotlib.figure.Figure at 0x10f207a50>
<matplotlib.figure.Figure at 0x10e573d50>
<matplotlib.figure.Figure at 0x10ea0dc90>
<matplotlib.figure.Figure at 0x10e5732d0>
<matplotlib.figure.Figure at 0x10ea0d890>
<matplotlib.figure.Figure at 0x10e7302d0>
<matplotlib.figure.Figure at 0x11030acd0>
<matplotlib.figure.Figure at 0x10ed21350>
<matplotlib.figure.Figure at 0x10e4f53d0>
<matplotlib.figure.Figure at 0x10e4e9650>
<matplotlib.figure.Figure at 0x110ac3210>
<matplotlib.figure.Figure at 0x10e4f5150>
<matplotlib.figure.Figure at 0x10fb07fd0>
<matplotlib.figure.Figure at 0x110ac3350>
<matplotlib.figure.Figure at 0x10ed21910>
<matplotlib.figure.Figure at 0x10ea8e7d0>
<matplotlib.figure.Figure at 0x10fb07a10>
<matplotlib.figure.Figure at 0x10e548b90>
<matplotlib.figure.Figure at 0x10e546a50>
<matplotlib.figure.Figure at 0x10fa6f6d0>
<matplotlib.figure.Figure at 0x10fa6fa50>
<matplotlib.figure.Figure at 0x10fadf850>
<matplotlib.figure.Figure at 0x10ea8e4d0>
<matplotlib.figure.Figure at 0x10fadf750>
<matplotlib.figure.Figure at 0x10e4debd0>
<matplotlib.figure.Figure at 0x10eec78d0>
<matplotlib.figure.Figure at 0x10fadf490>
<matplotlib.figure.Figure at 0x10e4de9d0>
<matplotlib.figure.Figure at 0x10e667ad0>
<matplotlib.figure.Figure at 0x10eec2b10>
<matplotlib.figure.Figure at 0x10e6676d0>
<matplotlib.figure.Figure at 0x10eec70d0>
<matplotlib.figure.Figure at 0x10e4dedd0>
<matplotlib.figure.Figure at 0x10ea37c10>
<matplotlib.figure.Figure at 0x10ea37f50>
<matplotlib.figure.Figure at 0x10e4f3690>
<matplotlib.figure.Figure at 0x110192350>
<matplotlib.figure.Figure at 0x10ea1e690>
<matplotlib.figure.Figure at 0x110139a50>
<matplotlib.figure.Figure at 0x110192150>
<matplotlib.figure.Figure at 0x10e4f3bd0>
<matplotlib.figure.Figure at 0x1101a8690>
<matplotlib.figure.Figure at 0x110139910>
<matplotlib.figure.Figure at 0x10ea37450>
<matplotlib.figure.Figure at 0x1101a8990>
<matplotlib.figure.Figure at 0x1101a8f10>
<matplotlib.figure.Figure at 0x11035a3d0>
<matplotlib.figure.Figure at 0x11034a250>
<matplotlib.figure.Figure at 0x11042c3d0>
<matplotlib.figure.Figure at 0x11034ac50>
<matplotlib.figure.Figure at 0x11042cf90>
<matplotlib.figure.Figure at 0x10eca7f90>
<matplotlib.figure.Figure at 0x10f0efa10>
<matplotlib.figure.Figure at 0x10ecc19d0>
<matplotlib.figure.Figure at 0x11035a490>
<matplotlib.figure.Figure at 0x109445f90>
<matplotlib.figure.Figure at 0x10ecc1150>
<matplotlib.figure.Figure at 0x110d696d0>
<matplotlib.figure.Figure at 0x10f6bbb90>
<matplotlib.figure.Figure at 0x1094458d0>
<matplotlib.figure.Figure at 0x110126090>
<matplotlib.figure.Figure at 0x110d69550>
<matplotlib.figure.Figure at 0x110126b90>
<matplotlib.figure.Figure at 0x110126510>
<matplotlib.figure.Figure at 0x110130b90>
<matplotlib.figure.Figure at 0x11011fa10>
<matplotlib.figure.Figure at 0x1103f9a50>
<matplotlib.figure.Figure at 0x110126950>
<matplotlib.figure.Figure at 0x11011f710>
<matplotlib.figure.Figure at 0x10fb78790>
<matplotlib.figure.Figure at 0x10f0d3c10>
<matplotlib.figure.Figure at 0x10fb78e90>
<matplotlib.figure.Figure at 0x110ba8590>
<matplotlib.figure.Figure at 0x10fb78e50>
<matplotlib.figure.Figure at 0x10fb78290>
<matplotlib.figure.Figure at 0x110ba88d0>
<matplotlib.figure.Figure at 0x1101e41d0>
<matplotlib.figure.Figure at 0x111335c50>
<matplotlib.figure.Figure at 0x1101e4450>
<matplotlib.figure.Figure at 0x10e55ce90>

In [132]:
hasattr(_d,'pose')


Out[132]:
True

In [ ]:


In [ ]: