fig1S33S1_ntsr.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. """Figure 1S33S1 Ntsr versions of fig1S33S1.py, use run -i fig1S33S1_ntsr.py. Currently used
  2. for rebuttal figure R2"""
  3. assert EXPTYPE == 'ntsrmvis'
  4. from matplotlib.patches import Rectangle
  5. chirptype = pd.read_csv('csv/ntsr_unit_celltypes_yannik.csv')
  6. chirptype.set_index(['msu'], inplace=True)
  7. ## strip plot max FMI of movie and grating meanrate and meanburstratio,
  8. ## each msu classified as chirp ON/OFF/transient/mixed by Yannik:
  9. np.random.seed(0) # to get identical horizontal jitter in strip plots on every run
  10. figsize = DEFAULTFIGURESIZE
  11. chirp2clr = {'On':green, 'Off':'red', 'Transient':'black', 'Mixed':'gray'}
  12. for stimtype in STIMTYPES:
  13. stimtypelabel = stimtype2axislabel[stimtype]
  14. for measure in ['meanrate', 'meanburstratio']:
  15. axislabel = measure2axislabel[measure]
  16. if axislabel.islower():
  17. axislabel = axislabel.capitalize()
  18. fmis, onoffs = [], []
  19. for msustr in mvigrtmsustrs:
  20. fmi = maxFMI.loc[msustr, 'none', stimtype][measure]
  21. if pd.isna(fmi):
  22. continue
  23. try:
  24. onoff = chirptype.loc[msustr]['clu_label']
  25. except KeyError:
  26. continue # no chirp cell type for this msu
  27. fmis.append(fmi)
  28. onoffs.append(onoff)
  29. fmis = np.asarray(fmis)
  30. onoffs = np.asarray(onoffs)
  31. onfmis = fmis[onoffs == 'ON-sust.']
  32. offfmis = fmis[onoffs == 'OFF-sust.']
  33. onofffmis = fmis[onoffs == 'ON-OFF-trans.']
  34. mixedfmis = fmis[onoffs == 'mixed']
  35. f, a = plt.subplots(figsize=figsize)
  36. wintitle('maxFMI chirp %s %s stripplot' % (stimtypelabel, measure))
  37. dfdict = {'On':onfmis, 'Off':offfmis, 'Transient':onofffmis, 'Mixed':mixedfmis}
  38. data = pd.DataFrame.from_dict(dfdict, orient='index').transpose()
  39. sns.stripplot(ax=a, data=data, palette=chirp2clr, clip_on=False,
  40. marker='.', size=np.sqrt(70))
  41. a.set_ylabel('FMI')
  42. a.set_xlim(0, 3)
  43. a.set_ylim(-1, 1)
  44. a.set_yticks([-1, 0, 1])
  45. a.spines['left'].set_position(('outward', 10))
  46. a.spines['bottom'].set_position(('outward', 5))
  47. #a.spines['bottom'].set_visible(False)
  48. #a.tick_params(bottom=False)
  49. plt.xticks(rotation=45)
  50. print(stimtype, measure)
  51. print(data)
  52. ## scatter plot grating meanrates, coloured by chirp ON sustained/OFF sustained/transient/mixed
  53. ## as classified by Yannik:
  54. figsize = DEFAULTFIGURESIZE
  55. logmin, logmax = -1.2, 2
  56. logticks = np.array([-1, 0, 1, 2])
  57. #log0min = logmin + 0.05
  58. for st8 in ['none']:#ALLST8S:
  59. f, a = plt.subplots(figsize=figsize)
  60. wintitle('opto meanrate grating %s chirp' % st8)
  61. rons, roffs, onoffs = [], [], []
  62. for mseustr in grtmseustrs:
  63. meanrate = grtresp.loc[mseustr, st8]['meanrate']
  64. msustr = mseustr2msustr(mseustr)
  65. try:
  66. onoff = chirptype.loc[msustr]['clu_label']
  67. except KeyError:
  68. continue # no chirp experiment for cell typing
  69. if meanrate.isna().any(): # missing one or both meanrates
  70. #print('%s: missing one or both opto conditions, skipping' % mseustr)
  71. continue
  72. rons.append(meanrate[True])
  73. roffs.append(meanrate[False])
  74. onoffs.append(onoff)
  75. #fig3.loc[mseustr, 'meanrate'] = meanrate[False], meanrate[True] # save
  76. rons = np.asarray(rons)
  77. roffs = np.asarray(roffs)
  78. onoffs = np.asarray(onoffs)
  79. clrs = []
  80. chirptype2clr = {'ON-sust.':green, 'OFF-sust.':'red', 'ON-OFF-trans.':'black',
  81. 'mixed':'gray'}
  82. for onoff in onoffs:
  83. clr = chirptype2clr[onoff]
  84. clrs.append(clr)
  85. # plot y=x line:
  86. xyline = [10**logmin, 10**logmax], [10**logmin, 10**logmax]
  87. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  88. # plot all points:
  89. a.scatter(rons, roffs, marker='.', c='None', edgecolor=clrs, s=DEFSZ)
  90. a.set_ylabel('Feedback FR (spk/s)')
  91. a.set_xlabel('Suppression FR (spk/s)')
  92. a.set_xscale('log')
  93. a.set_yscale('log')
  94. a.set_xlim(10**logmin, 10**logmax)
  95. a.set_ylim(10**logmin, 10**logmax)
  96. a.set_xticks(10.0**logticks)
  97. a.set_yticks(a.get_xticks()) # make log scale y ticks the same as x ticks
  98. axes_disable_scientific(a)
  99. a.minorticks_off()
  100. a.set_aspect('equal')
  101. ## scatter plot movie meanrates, coloured by chirp ON sustained/OFF sustained/transient/mixed
  102. ## as classified by Yannik:
  103. figsize = DEFAULTFIGURESIZE
  104. logmin, logmax = -1.2, 2
  105. logticks = np.array([-1, 0, 1, 2])
  106. #log0min = logmin + 0.05
  107. for st8 in ['none']:#ALLST8S:
  108. f, a = plt.subplots(figsize=figsize)
  109. wintitle('opto meanrate movie nat %s chirp' % st8)
  110. rons, roffs, onoffs = [], [], []
  111. for mseustr in mvimseustrs:
  112. meanrate = mviresp.loc[mseustr, 'nat', st8]['meanrate']
  113. msustr = mseustr2msustr(mseustr)
  114. try:
  115. onoff = chirptype.loc[msustr]['clu_label']
  116. except KeyError:
  117. continue # no chirp experiment for cell typing
  118. if meanrate.isna().any(): # missing one or both meanrates
  119. #print('%s: missing one or both opto conditions, skipping' % mseustr)
  120. continue
  121. print(mseustr)
  122. rons.append(meanrate[True])
  123. roffs.append(meanrate[False])
  124. onoffs.append(onoff)
  125. rons = np.asarray(rons)
  126. roffs = np.asarray(roffs)
  127. clrs = []
  128. chirptype2clr = {'ON-sust.':green, 'OFF-sust.':'red', 'ON-OFF-trans.':'black',
  129. 'mixed':'gray'}
  130. for onoff in onoffs:
  131. clr = chirptype2clr[onoff]
  132. clrs.append(clr)
  133. # plot y=x line:
  134. xyline = [10**logmin, 10**logmax], [10**logmin, 10**logmax]
  135. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  136. # plot all points:
  137. a.scatter(rons, roffs, marker='.', c='None', edgecolor=clrs, s=DEFSZ)
  138. a.set_ylabel('Feedback FR (spk/s)')
  139. a.set_xlabel('Suppression FR (spk/s)')
  140. a.set_xscale('log')
  141. a.set_yscale('log')
  142. a.set_xlim(10**logmin, 10**logmax)
  143. a.set_ylim(10**logmin, 10**logmax)
  144. a.set_xticks(10.0**logticks)
  145. a.set_yticks(a.get_xticks()) # make log scale y ticks the same as x ticks
  146. axes_disable_scientific(a)
  147. a.minorticks_off()
  148. a.set_aspect('equal')
  149. ## scatter plot grating burst ratio, coloured by chirp ON sustained/OFF sustained/transient/mixed
  150. ## as classified by Yannik:
  151. figsize = DEFAULTFIGURESIZE
  152. logmin, logmax = -3.55, 0
  153. logticks = np.array([-3, -2, -1, 0])
  154. for st8 in ['none']:#ALLST8S:
  155. f, a = plt.subplots(figsize=figsize)
  156. wintitle('opto burst ratio grating %s chirp' % st8)
  157. brons, broffs, onoffs = [], [], []
  158. for mseustr in grtmseustrs:
  159. br = grtresp.loc[mseustr, st8]['meanburstratio']
  160. msustr = mseustr2msustr(mseustr)
  161. try:
  162. onoff = chirptype.loc[msustr]['clu_label']
  163. except KeyError:
  164. continue # no chirp experiment for cell typing
  165. if br.isna().any(): # missing for at least one opto condition
  166. continue
  167. brons.append(br[True])
  168. broffs.append(br[False])
  169. onoffs.append(onoff)
  170. #fig3.loc[mseustr, 'meanburstratio'] = br[False], br[True] # save
  171. brons, broffs, onoffs = np.asarray(brons), np.asarray(broffs), np.asarray(onoffs)
  172. clrs = []
  173. chirptype2clr = {'ON-sust.':green, 'OFF-sust.':'red', 'ON-OFF-trans.':'black',
  174. 'mixed':'gray'}
  175. for onoff in onoffs:
  176. clr = chirptype2clr[onoff]
  177. clrs.append(clr)
  178. # plot y=x line:
  179. xyline = [10**logmin, 10**logmax], [10**logmin, 10**logmax]
  180. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  181. # plot all points:
  182. a.scatter(brons, broffs, marker='.', c='None', edgecolor=clrs, s=DEFSZ)
  183. a.set_xlabel('Suppression BR') # keep it short to maximize space for axes
  184. a.set_ylabel('Feedback BR')
  185. a.set_xscale('log')
  186. a.set_yscale('log')
  187. a.set_xlim(10**logmin, 10**logmax)
  188. a.set_ylim(10**logmin, 10**logmax)
  189. a.set_xticks(10.0**logticks)
  190. a.set_yticks(a.get_xticks()) # make log scale y ticks the same as x ticks
  191. a.minorticks_off()
  192. axes_disable_scientific(a)
  193. a.set_aspect('equal')
  194. ## scatter plot movie burst ratio, coloured by chirp ON sustained/OFF sustained/transient/mixed
  195. ## as classified by Yannik:
  196. figsize = DEFAULTFIGURESIZE
  197. logmin, logmax = -3.55, 0
  198. logticks = np.array([-3, -2, -1, 0])
  199. for st8 in ['none']:#ALLST8S:
  200. f, a = plt.subplots(figsize=figsize)
  201. wintitle('opto burst ratio movie nat %s chirp' % st8)
  202. brons, broffs, onoffs = [], [], []
  203. for mseustr in mvimseustrs:
  204. br = mviresp.loc[mseustr, 'nat', st8]['meanburstratio']
  205. msustr = mseustr2msustr(mseustr)
  206. msustr = mseustr2msustr(mseustr)
  207. try:
  208. onoff = chirptype.loc[msustr]['clu_label']
  209. except KeyError:
  210. continue # no chirp experiment for cell typing
  211. if br.isna().any(): # missing for at least one opto condition
  212. continue
  213. brons.append(br[True])
  214. broffs.append(br[False])
  215. onoffs.append(onoff)
  216. #fig3.loc[mseustr, 'meanburstratio'] = br[False], br[True] # save
  217. brons, broffs, onoffs = np.asarray(brons), np.asarray(broffs), np.asarray(onoffs)
  218. clrs = []
  219. chirptype2clr = {'ON-sust.':green, 'OFF-sust.':'red', 'ON-OFF-trans.':'black',
  220. 'mixed':'gray'}
  221. for onoff in onoffs:
  222. clr = chirptype2clr[onoff]
  223. clrs.append(clr)
  224. # plot y=x line:
  225. xyline = [10**logmin, 10**logmax], [10**logmin, 10**logmax]
  226. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  227. # plot all points:
  228. a.scatter(brons, broffs, marker='.', c='None', edgecolor=clrs, s=DEFSZ)
  229. a.set_xlabel('Suppression BR') # keep it short to maximize space for axes
  230. a.set_ylabel('Feedback BR')
  231. a.set_xscale('log')
  232. a.set_yscale('log')
  233. a.set_xlim(10**logmin, 10**logmax)
  234. a.set_ylim(10**logmin, 10**logmax)
  235. a.set_xticks(10.0**logticks)
  236. a.set_yticks(a.get_xticks()) # make log scale y ticks the same as x ticks
  237. a.minorticks_off()
  238. axes_disable_scientific(a)
  239. a.set_aspect('equal')
  240. #TRANSTHRESH = 0.2
  241. #ONOFFTHRESH = 0.2
  242. ## generate celltype vs chirptype on/off/transient/other matrix, requires that celltype code
  243. ## from fig1S33S1.py has been run with EXPTYPE == 'ntsrmvis' set.
  244. ## The two classification methods correspond very poorly:
  245. # join on msu index, those rows that don't overlap have chirp type fields left as NaN
  246. celltypechirptype = celltype.join(chirptype)
  247. mat = np.zeros((4, 4), dtype=int)
  248. chrptypestr2i = {'ON-sust.':0, 'OFF-sust.':1, 'ON-OFF-trans.':2, 'mixed':3}
  249. mvitypestr2i = {'On':0, 'Off':1, 'Trans':2, '':3}
  250. for msustr, row in celltypechirptype.iterrows():
  251. chrptypestr = row['clu_label']
  252. if pd.isna(chrptypestr):
  253. continue # mvi unit doesn't have a chirp experiment?
  254. onoff = row['onoff']
  255. trans = row['trans']
  256. mvitypestr = ''
  257. if trans >= TRANSTHRESH: # first try and classify by trans
  258. mvitypestr = 'Trans'
  259. elif onoff >= ONOFFTHRESH: # try and classify by on/off
  260. mvitypestr = 'On'
  261. elif onoff < -ONOFFTHRESH:
  262. mvitypestr = 'Off'
  263. chrptypei = chrptypestr2i[chrptypestr]
  264. mvitypei = mvitypestr2i[mvitypestr]
  265. mat[mvitypei, chrptypei] += 1
  266. figsize = 4, 3
  267. f, a = plt.subplots(figsize=figsize)
  268. wintitle('celltype vs chirptype matrix ONOFFTHRESH=%.2f TRANSTHRESH=%.2f'
  269. % (ONOFFTHRESH, TRANSTHRESH))
  270. #a.imshow(mat, origin='upper', aspect='equal', cmap='gray')
  271. img = a.matshow(mat)
  272. #a.set_xticks(np.arange(4))
  273. #a.set_yticks(np.arange(4))
  274. #a.set_xticklabels(list(chrptypestr2i.keys()))
  275. #a.set_yticklabels(list(mvitypestr2i.keys()))
  276. f.colorbar(img, ticks=[mat.min(), mat.max()], label='Unit count')
  277. a.set_xlabel('Chirp type')
  278. a.set_ylabel('Movie onset type')
  279. f.tight_layout(pad=1)