fig5.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. """Figure 5 and 5S1 plots, use run -i fig5.py"""
  2. mi = pd.MultiIndex.from_product([mvimseustrs, ST8S, OPTOS], names=['mseu', 'st8', 'opto'])
  3. columns = ['trialis', 'rates', 'burstratios', 'meanrate', 'meanburstratio',
  4. 'spars', 'rel', 'meanpkw', 'snr']
  5. fig5 = pd.DataFrame(index=mi, columns=columns) # excludes kind and opto
  6. # tweak exactly how much horizontal space to use for raster plots and PSTHs:
  7. PLOTOFFSETS = -0.45, 0.45
  8. # plot movie rasters for each unit by kind, state and opto condition:
  9. # copied and slightly modified from fig1.py:
  10. showbursts = True
  11. trialiis = None #np.arange(120) # plot only these trials, None plots all trials
  12. for mseustr in mvimseu2exmpli: # mvimseustrs
  13. if mseustr != 'PVCre_2018_0003_s03_e03_u51': # plot only this one
  14. continue
  15. for kind in MVIKINDS:
  16. for st8 in ['run', 'sit']:
  17. for opto in OPTOS:
  18. dt = mviresp.loc[mseustr, kind, st8, opto]['dt'] # stimulus duration (s)
  19. #wdt = -PLOTOFFSETS[0] + dt + PLOTOFFSETS[1] # wide raster duration, sec
  20. tmin, tmax = 0 + PLOTOFFSETS[0], dt + PLOTOFFSETS[1]
  21. optotrange = mviresp.loc[mseustr, kind, st8, opto]['optotrange']
  22. raster = mviresp.loc[mseustr, kind, st8, opto]['wraster']
  23. if np.any(pd.isna(raster)): # no raster for this condition
  24. continue
  25. title = '%s movie %s %s %s raster' % (mseustr, kind, st8, opto)
  26. if trialiis is not None:
  27. raster = raster[trialiis]
  28. title += ' %dtrials' % len(trialiis)
  29. burstis = None
  30. if showbursts:
  31. wburstis = mviresp.loc[mseustr, kind, st8, opto]['wburstis']
  32. a = simpletraster(raster=raster, alpha=0.5, s=1, dt=dt, offsets=PLOTOFFSETS,
  33. title=title, inchespersec=1.5*RASTERSCALEX,
  34. inchespertrial=1/25*RASTERSCALEX,
  35. xaxis=True, burstis=wburstis)
  36. if opto:
  37. # plot horizontal line signifying opto ON period, just above axes:
  38. ton, toff = optotrange
  39. a.hlines(-5, ton, toff, colors=optoblue, lw=4, clip_on=False,
  40. in_layout=False)
  41. # plot horizontal line signifying stimulus period, just above axes:
  42. a.hlines(-2, 0, dt, colors='k', lw=4, clip_on=False, in_layout=False)
  43. # plot vertical coloured line just right of axes:
  44. #vlinexpos = dt + PLOTOFFSETS[1] + wdt*0.01
  45. #y0, y1 = a.get_ylim()
  46. #clr = st82clr[st8]
  47. #alpha = opto2alpha[opto]
  48. #a.vlines(vlinexpos, y0, y1, colors=clr, lw=4, alpha=alpha, clip_on=False,
  49. # in_layout=False)
  50. a.set_xlim(tmin, tmax)
  51. # plot movie PSTHs for each unit by kind, overplot state and opto combinations:
  52. # copied and slightly modified from fig1.py:
  53. for mseustr in mvimseu2exmpli: #mvimseustrs
  54. if mseustr != 'PVCre_2018_0003_s03_e03_u51': # plot only this one
  55. continue
  56. for kind in MVIKINDS:
  57. wt = mviresp.loc[mseustr, kind]['wt'] # DataFrame
  58. wpsth = mviresp.loc[mseustr, kind]['wpsth'] # DataFrame
  59. wbpsth = mviresp.loc[mseustr, kind]['wbpsth'] # DataFrame
  60. #t = mviresp.loc[mseustr, kind]['t'] # DataFrame
  61. psth = mviresp.loc[mseustr, kind]['psth'] # DataFrame
  62. if np.isnan(np.hstack(wpsth)).any(): # no PSTH for at least one condition for this mseu
  63. continue
  64. optorho, optorho_p = scipy.stats.pearsonr(psth['none', False], psth['none', True])
  65. runsitrho, runsitrho_p = scipy.stats.pearsonr(psth['run', False], psth['sit', False])
  66. skewoff = scipy.stats.skew(psth['none', False])
  67. skewon = scipy.stats.skew(psth['none', True])
  68. skewrun = scipy.stats.skew(psth['run', False])
  69. skewsit = scipy.stats.skew(psth['sit', False])
  70. _, optoKS_p = ks_2samp(psth['none', False], psth['none', True])
  71. _, runsitKS_p = ks_2samp(psth['run', False], psth['sit', False])
  72. print('%s example PSTH:\n'
  73. 'optorho=%g optorho_p=%g skewoff=%g skewon=%g optoKS_p=%g\n'
  74. 'runsitrho=%g runsitrho_p=%g skewrun=%g skewsit=%g runsitKS_p=%g'
  75. % (mseustr,
  76. optorho, optorho_p, skewoff, skewon, optoKS_p,
  77. runsitrho, runsitrho_p, skewrun, skewsit, runsitKS_p))
  78. for st8combo, optocombo in zip(ST8COMBOS, OPTOCOMBOS):
  79. st8combostr = ' '.join(st8combo)
  80. optocombostr = ' '.join([str(opto) for opto in optocombo])
  81. dt = mviresp.loc[mseustr, kind, 'none']['dt'].mean() # mean stimulus duration (s)
  82. wdt = -PLOTOFFSETS[0] + dt + PLOTOFFSETS[1] # wide raster duration, sec
  83. tmin, tmax = 0 + PLOTOFFSETS[0], dt + PLOTOFFSETS[1]
  84. #figsize = 0.872 + wdt*1.5*RASTERSCALEX, PSTHHEIGHT
  85. figsize = 0.95 + wdt*1.5*RASTERSCALEX, PSTHHEIGHT
  86. f, a = plt.subplots(figsize=figsize)
  87. title = '%s %s %s %s PSTH' % (mseustr, kind, st8combostr, optocombostr)
  88. wintitle(title)
  89. # subsample as in PSTH scatter plots, and plot all 4 st8/opto combinations:
  90. for st8 in st8combo:
  91. color = st82clr[st8]
  92. for opto in optocombo:
  93. if st8combo == ['run', 'sit'] and optocombo == [True]:
  94. optoalpha = 1
  95. else:
  96. optoalpha = opto2alpha[opto]
  97. if optocombo == [False]: # desaturate bursts by st8, not opto
  98. burstalpha = st82alpha[st8]
  99. else:
  100. burstalpha = opto2alpha[opto]
  101. c = desat(color, optoalpha) # do manual alpha mixing
  102. bc = desat(burstclr, burstalpha) # do manual alpha mixing
  103. fb = opto2fb[opto].title()
  104. if st8 == 'none':
  105. label = fb
  106. else:
  107. label = ', '.join([fb, st8.title()])
  108. a.plot(wt[st8, opto][::ssx], wpsth[st8, opto][::ssx],
  109. '-', color=c, label=label)
  110. #a.plot(t[st8, opto][::ssx], wbpsth[st8, opto][::ssx],
  111. # '-', color=bc, label=label+', Burst')
  112. l = a.legend(frameon=False)
  113. l.set_draggable(True)
  114. a.set_xlabel('Time (s)')
  115. a.set_ylabel('Firing rate (spk/s)')
  116. a.set_xlim(tmin, tmax)
  117. a.set_ylim(-2.75, 57)
  118. # plot horizontal line signifying stimulus period, just below data:
  119. ymin, ymax = a.get_ylim()
  120. a.hlines(-ymax*0.025, 0, dt, colors='k', lw=4, clip_on=False, in_layout=False)
  121. a.set_ylim(ymin, ymax) # restore y limits from before plotting the hline
  122. # scatter plot movie run vs sit meanrate, during feedback condition:
  123. figsize = DEFAULTFIGURESIZE[0]*1.05, DEFAULTFIGURESIZE[1] # tweak to make space for log units
  124. logmin, logmax = -2, 2
  125. logticks = np.array([-2, 0, 2])
  126. for kind in ['nat']:#MVIKINDS:
  127. for opto in OPTOS:
  128. f, a = plt.subplots(figsize=figsize)
  129. wintitle('runsit meanrate movie %s %s' % (kind, opto))
  130. rruns, rsits, sgnfs, exmplis, exmplmseustrs, normlis = [], [], [], [], [], []
  131. keptmseui = 0 # manually init and increment instead of using enumerate()
  132. for mseustr in mvimseustrs:
  133. meanrate = mviresp.loc[mseustr, kind, ST8S, opto]['meanrate']
  134. snr = mviresp.loc[mseustr, kind, ST8S, opto]['snr']
  135. if meanrate.isna().any(): # missing one or both meanrates
  136. continue
  137. if (snr < SNRTHRESH).all(): # neither condition has decent SNR
  138. continue
  139. rrun, rsit = meanrate.values
  140. rruns.append(rrun)
  141. rsits.append(rsit)
  142. trialis = mviresp.loc[mseustr, kind, ST8S, opto]['trialis']
  143. rates = mviresp.loc[mseustr, kind, ST8S, opto]['rates']
  144. runrates = rates.xs('run', level='st8').iloc[0]
  145. sitrates = rates.xs('sit', level='st8').iloc[0]
  146. _, pval = ttest_ind(runrates, sitrates, equal_var=False)
  147. sgnfs.append(pval < SCATTERPTHRESH) # bool
  148. fig5.loc[(mseustr, ST8S, opto), 'meanrate'] = rrun, rsit # save
  149. fig5.loc[(mseustr, ST8S, opto), 'trialis'] = trialis.values # for trial-wise joins
  150. fig5.loc[(mseustr, ST8S, opto), 'rates'] = rates.values # save trial-wise values
  151. if mvimseu2exmpli.get(mseustr) == fig5exmpli:
  152. exmplis.append(keptmseui)
  153. exmplmseustrs.append(mseustr)
  154. else:
  155. normlis.append(keptmseui)
  156. keptmseui += 1 # manually increment
  157. rruns = np.asarray(rruns)
  158. rsits = np.asarray(rsits)
  159. sgnfs = np.asarray(sgnfs)
  160. # plot y=x line:
  161. xyline = [10**logmin, 10**logmax], [10**logmin, 10**logmax]
  162. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  163. insgnfis, = np.where(sgnfs == False)
  164. sgnfis, = np.where(sgnfs == True)
  165. normlinsgnfis = np.intersect1d(normlis, insgnfis)
  166. normlsgnfis = np.intersect1d(normlis, sgnfis)
  167. # plot normal (non-example) insignificant points:
  168. c = desat(black, SGNF2ALPHA[False]) # do manual alpha mixing
  169. a.scatter(rsits[normlinsgnfis], rruns[normlinsgnfis], clip_on=False,
  170. marker='.', c='None', edgecolor=c, s=DEFSZ)
  171. # plot normal (non-example) significant points:
  172. c = desat(black, SGNF2ALPHA[True]) # do manual alpha mixing
  173. a.scatter(rsits[normlsgnfis], rruns[normlsgnfis], clip_on=False,
  174. marker='.', c='None', edgecolor=c, s=DEFSZ)
  175. # plot example points, one at a time:
  176. for exmpli, mseustr in zip(exmplis, exmplmseustrs):
  177. marker = exmpli2mrk[mvimseu2exmpli[mseustr]]
  178. c = exmpli2clr[mvimseu2exmpli[mseustr]]
  179. sz = exmpli2sz[mvimseu2exmpli[mseustr]]
  180. lw = exmpli2lw[mvimseu2exmpli[mseustr]]
  181. a.scatter(rsits[exmpli], rruns[exmpli], clip_on=False,
  182. marker=marker, c=c, s=sz, lw=lw)
  183. a.set_xlabel('Sit FR (spk/s)')
  184. a.set_ylabel('Run FR (spk/s)')
  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. a.spines['left'].set_position(('outward', 4))
  195. a.spines['bottom'].set_position(('outward', 4))
  196. #t, p = ttest_rel(rsits, rruns) # paired t-test
  197. #a.add_artist(AnchoredText('p$=$%.2g' % p, loc='lower right', frameon=False))
  198. # scatter plot movie run vs sit burst ratio, during feedback condition:
  199. figsize = DEFAULTFIGURESIZE[0]*1.06, DEFAULTFIGURESIZE[1] # tweak to make space for log units
  200. logmin, logmax = -3.55, 0
  201. logticks = np.array([-3, -2, -1, 0])
  202. for kind in ['nat']:#MVIKINDS:
  203. for opto in OPTOS:
  204. f, a = plt.subplots(figsize=figsize)
  205. wintitle('runsit burst ratio movie %s %s' % (kind, opto))
  206. brruns, brsits, sgnfs, exmplis, exmplmseustrs, normlis = [], [], [], [], [], []
  207. keptmseui = 0 # manually init and increment instead of using enumerate()
  208. for mseustr in mvimseustrs:
  209. br = mviresp.loc[mseustr, kind, ST8S, opto]['meanburstratio']
  210. snr = mviresp.loc[mseustr, kind, ST8S, opto]['snr']
  211. if br.isna().any(): # missing one or both values
  212. continue
  213. if (snr < SNRTHRESH).all(): # neither condition has decent SNR
  214. continue
  215. brrun, brsit = br.values
  216. brruns.append(brrun)
  217. brsits.append(brsit)
  218. burstratios = mviresp.loc[mseustr, kind, ST8S, opto]['burstratios']
  219. runburstratios = burstratios.xs('run', level='st8').iloc[0]
  220. sitburstratios = burstratios.xs('sit', level='st8').iloc[0]
  221. _, pval = ttest_ind(runburstratios, sitburstratios, equal_var=False)
  222. sgnfs.append(pval < SCATTERPTHRESH) # bool
  223. fig5.loc[(mseustr, ST8S, opto), 'meanburstratio'] = brrun, brsit # save
  224. fig5.loc[(mseustr, ST8S, opto), 'burstratios'] = burstratios.values # save trial-wise
  225. if mvimseu2exmpli.get(mseustr) == fig5exmpli:
  226. exmplis.append(keptmseui)
  227. exmplmseustrs.append(mseustr)
  228. else:
  229. normlis.append(keptmseui)
  230. keptmseui += 1 # manually increment
  231. brruns = np.asarray(brruns)
  232. brsits = np.asarray(brsits)
  233. sgnfs = np.asarray(sgnfs)
  234. # plot y=x line:
  235. xyline = [10**logmin, 10**logmax], [10**logmin, 10**logmax]
  236. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  237. insgnfis, = np.where(sgnfs == False)
  238. sgnfis, = np.where(sgnfs == True)
  239. normlinsgnfis = np.intersect1d(normlis, insgnfis)
  240. normlsgnfis = np.intersect1d(normlis, sgnfis)
  241. # plot normal (non-example) insignificant points:
  242. c = desat(black, SGNF2ALPHA[False]) # do manual alpha mixing
  243. a.scatter(brsits[normlinsgnfis], brruns[normlinsgnfis], clip_on=True,
  244. marker='.', c='None', edgecolor=c, s=DEFSZ) # clip_on=False fails
  245. # plot normal (non-example) significant points:
  246. c = desat(black, SGNF2ALPHA[True]) # do manual alpha mixing
  247. a.scatter(brsits[normlsgnfis], brruns[normlsgnfis], clip_on=True,
  248. marker='.', c='None', edgecolor=c, s=DEFSZ) # clip_on=False fails
  249. # plot example points, one at a time:
  250. for exmpli, mseustr in zip(exmplis, exmplmseustrs):
  251. marker = exmpli2mrk[mvimseu2exmpli[mseustr]]
  252. c = exmpli2clr[mvimseu2exmpli[mseustr]]
  253. sz = exmpli2sz[mvimseu2exmpli[mseustr]]
  254. lw = exmpli2lw[mvimseu2exmpli[mseustr]]
  255. a.scatter(brsits[exmpli], brruns[exmpli], clip_on=False,
  256. marker=marker, c=c, s=sz, lw=lw)
  257. a.set_xlabel('Sit BR')
  258. a.set_ylabel('Run BR')
  259. a.set_xscale('log')
  260. a.set_yscale('log')
  261. a.set_xlim(10**logmin, 10**logmax)
  262. a.set_ylim(10**logmin, 10**logmax)
  263. a.set_xticks(10.0**logticks)
  264. a.set_yticks(a.get_xticks()) # make log scale y ticks the same as x ticks
  265. a.minorticks_off()
  266. axes_disable_scientific(a)
  267. a.set_aspect('equal')
  268. a.spines['left'].set_position(('outward', 4))
  269. a.spines['bottom'].set_position(('outward', 4))
  270. #t, p = ttest_rel(brsits, brruns) # paired t-test
  271. #a.add_artist(AnchoredText('p$=$%.2g' % p, loc='upper left', frameon=False))
  272. # scatter plot movie run vs sit sparseness, during feedback condition:
  273. figsize = DEFAULTFIGURESIZE
  274. linmin, linmax, linstep = 0, 1, 0.5
  275. ticks = np.arange(intround(linmin), intround(linmax)+linstep, linstep)
  276. for kind in ['nat']:#MVIKINDS:
  277. for opto in OPTOS:
  278. f, a = plt.subplots(figsize=figsize)
  279. wintitle('runsit sparseness movie %s %s' % (kind, opto))
  280. sparsruns, sparssits, exmplis, exmplmseustrs, normlis = [], [], [], [], []
  281. keptmseui = 0 # manually init and increment instead of using enumerate()
  282. for mseustr in mvimseustrs:
  283. spars = mviresp.loc[mseustr, kind, ST8S, opto]['spars']
  284. snr = mviresp.loc[mseustr, kind, ST8S, opto]['snr']
  285. if spars.isna().any(): # missing one or both values
  286. continue
  287. if (snr < SNRTHRESH).all(): # neither condition has decent SNR
  288. continue
  289. sparsrun, sparssit = spars.values
  290. sparsruns.append(sparsrun)
  291. sparssits.append(sparssit)
  292. fig5.loc[(mseustr, ST8S, opto), 'spars'] = sparsrun, sparssit # save
  293. if mvimseu2exmpli.get(mseustr) == fig5exmpli:
  294. exmplis.append(keptmseui)
  295. exmplmseustrs.append(mseustr)
  296. else:
  297. normlis.append(keptmseui)
  298. keptmseui += 1 # manually increment
  299. sparsruns = np.asarray(sparsruns)
  300. sparssits = np.asarray(sparssits)
  301. # plot y=x line:
  302. xyline = [linmin, linmax], [linmin, linmax]
  303. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  304. # plot normal (non-example) points:
  305. a.scatter(sparssits[normlis], sparsruns[normlis], clip_on=False,
  306. marker='.', c='None', edgecolor='black', s=DEFSZ)
  307. # plot example points, one at a time:
  308. for exmpli, mseustr in zip(exmplis, exmplmseustrs):
  309. marker = exmpli2mrk[mvimseu2exmpli[mseustr]]
  310. c = exmpli2clr[mvimseu2exmpli[mseustr]]
  311. sz = exmpli2sz[mvimseu2exmpli[mseustr]]
  312. lw = exmpli2lw[mvimseu2exmpli[mseustr]]
  313. a.scatter(sparssits[exmpli], sparsruns[exmpli], clip_on=False,
  314. marker=marker, c=c, s=sz, lw=lw)
  315. a.set_xlabel('Sit sparseness')
  316. a.set_ylabel('Run sparseness')
  317. a.set_xlim(linmin, linmax)
  318. a.set_ylim(linmin, linmax)
  319. a.set_xticks(ticks)
  320. a.set_yticks(ticks)
  321. a.set_aspect('equal')
  322. a.spines['left'].set_position(('outward', 4))
  323. a.spines['bottom'].set_position(('outward', 4))
  324. #t, p = ttest_rel(sparssits, sparsruns) # paired t-test
  325. #a.add_artist(AnchoredText('p$=$%.2g' % p, loc='upper left', frameon=False))
  326. # scatter plot movie run vs sit reliability, during feedback condition:
  327. figsize = DEFAULTFIGURESIZE[0]*0.98, DEFAULTFIGURESIZE[1] # tweak down to match others
  328. linmin, linmax = 0, 0.63
  329. ticks = 0, 0.5
  330. for kind in ['nat']:#MVIKINDS:
  331. for opto in OPTOS:
  332. f, a = plt.subplots(figsize=figsize)
  333. wintitle('runsit reliability movie %s %s' % (kind, opto))
  334. relruns, relsits, sgnfs, exmplis, exmplmseustrs, normlis = [], [], [], [], [], []
  335. keptmseui = 0 # manually init and increment instead of using enumerate()
  336. for mseustr in mvimseustrs:
  337. rel = mviresp.loc[mseustr, kind, ST8S, opto]['rel']
  338. snr = mviresp.loc[mseustr, kind, ST8S, opto]['snr']
  339. if rel.isna().any(): # missing one or both values
  340. continue
  341. if (snr < SNRTHRESH).all(): # neither condition has decent SNR
  342. continue
  343. relrun, relsit = rel.values
  344. relruns.append(relrun)
  345. relsits.append(relsit)
  346. rhos = mviresp.loc[mseustr, kind, ST8S, opto]['rhos']
  347. runrhos = rhos.xs('run', level='st8').iloc[0]
  348. sitrhos = rhos.xs('sit', level='st8').iloc[0]
  349. _, pval = ttest_ind(runrhos, sitrhos, equal_var=False)
  350. sgnfs.append(pval < SCATTERPTHRESH) # bool
  351. fig5.loc[(mseustr, ST8S, opto), 'rel'] = relrun, relsit # save
  352. if mvimseu2exmpli.get(mseustr) == fig5exmpli:
  353. exmplis.append(keptmseui)
  354. exmplmseustrs.append(mseustr)
  355. else:
  356. normlis.append(keptmseui)
  357. keptmseui += 1 # manually increment
  358. relruns = np.asarray(relruns)
  359. relsits = np.asarray(relsits)
  360. sgnfs = np.asarray(sgnfs)
  361. # plot y=x line:
  362. xyline = [linmin, linmax], [linmin, linmax]
  363. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  364. insgnfis, = np.where(sgnfs == False)
  365. sgnfis, = np.where(sgnfs == True)
  366. normlinsgnfis = np.intersect1d(normlis, insgnfis)
  367. normlsgnfis = np.intersect1d(normlis, sgnfis)
  368. # plot normal (non-example) insignificant points:
  369. c = desat(black, SGNF2ALPHA[False]) # do manual alpha mixing
  370. a.scatter(relsits[normlinsgnfis], relruns[normlinsgnfis], clip_on=False,
  371. marker='.', c='None', edgecolor=c, s=DEFSZ)
  372. # plot normal (non-example) significant points:
  373. c = desat(black, SGNF2ALPHA[True]) # do manual alpha mixing
  374. a.scatter(relsits[normlsgnfis], relruns[normlsgnfis], clip_on=False,
  375. marker='.', c='None', edgecolor=c, s=DEFSZ)
  376. # plot example points, one at a time:
  377. for exmpli, mseustr in zip(exmplis, exmplmseustrs):
  378. marker = exmpli2mrk[mvimseu2exmpli[mseustr]]
  379. c = exmpli2clr[mvimseu2exmpli[mseustr]]
  380. sz = exmpli2sz[mvimseu2exmpli[mseustr]]
  381. lw = exmpli2lw[mvimseu2exmpli[mseustr]]
  382. a.scatter(relsits[exmpli], relruns[exmpli], clip_on=False,
  383. marker=marker, c=c, s=sz, lw=lw)
  384. a.set_xlabel('Sit reliability')
  385. a.set_ylabel('Run reliability')
  386. a.set_xlim(linmin, linmax)
  387. a.set_ylim(linmin, linmax)
  388. a.set_xticks(ticks)
  389. a.set_yticks(ticks)
  390. a.set_aspect('equal')
  391. a.spines['left'].set_position(('outward', 4))
  392. a.spines['bottom'].set_position(('outward', 4))
  393. #t, p = ttest_rel(relsits, relruns) # paired t-test
  394. #a.add_artist(AnchoredText('p$=$%.2g' % p, loc='upper left', frameon=False))
  395. # scatter plot movie sit vs. run SNR:
  396. figsize = DEFAULTFIGURESIZE
  397. linmin, linmax = 0, 0.65
  398. ticks = 0, 0.5
  399. for kind in ['nat']:#MVIKINDS:
  400. for opto in OPTOS:
  401. f, a = plt.subplots(figsize=figsize)
  402. wintitle('runsit SNR movie %s %s' % (kind, opto))
  403. snrruns, snrsits, exmplis, exmplmseustrs, normlis = [], [], [], [], []
  404. keptmseui = 0 # manually init and increment instead of using enumerate()
  405. for mseustr in mvimseustrs:
  406. snr = mviresp.loc[mseustr, kind, ST8S, opto]['snr']
  407. if snr.isna().any(): # missing one or both values
  408. continue
  409. if (snr < SNRTHRESH).all(): # neither condition has decent SNR
  410. continue
  411. snrrun, snrsit = snr.values
  412. snrruns.append(snrrun)
  413. snrsits.append(snrsit)
  414. fig5.loc[(mseustr, ST8S, opto), 'snr'] = snrrun, snrsit # save
  415. if mvimseu2exmpli.get(mseustr) == fig5exmpli:
  416. exmplis.append(keptmseui)
  417. exmplmseustrs.append(mseustr)
  418. else:
  419. normlis.append(keptmseui)
  420. keptmseui += 1 # manually increment
  421. snrruns = np.asarray(snrruns)
  422. snrsits = np.asarray(snrsits)
  423. # plot y=x line:
  424. xyline = [linmin, linmax], [linmin, linmax]
  425. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  426. # plot normal (non-example) points:
  427. a.scatter(snrsits[normlis], snrruns[normlis], clip_on=False,
  428. marker='.', c='None', edgecolor='black', s=DEFSZ)
  429. # plot example points, one at a time:
  430. for exmpli, mseustr in zip(exmplis, exmplmseustrs):
  431. marker = exmpli2mrk[mvimseu2exmpli[mseustr]]
  432. c = exmpli2clr[mvimseu2exmpli[mseustr]]
  433. sz = exmpli2sz[mvimseu2exmpli[mseustr]]
  434. lw = exmpli2lw[mvimseu2exmpli[mseustr]]
  435. a.scatter(snrsits[exmpli], snrruns[exmpli], clip_on=False,
  436. marker=marker, c=c, s=sz, lw=lw)
  437. a.set_xlabel('Sit SNR')
  438. a.set_ylabel('Run SNR')
  439. a.set_xlim(linmin, linmax)
  440. a.set_ylim(linmin, linmax)
  441. a.set_xticks(ticks)
  442. a.set_yticks(ticks)
  443. a.set_aspect('equal')
  444. a.spines['left'].set_position(('outward', 4))
  445. a.spines['bottom'].set_position(('outward', 4))
  446. #t, p = ttest_rel(snrsits, snrruns) # paired t-test
  447. #a.add_artist(AnchoredText('p$=$%.2g' % p, loc='upper left', frameon=False))
  448. # scatter plot movie run vs sit mean peak widths, during feedback condition:
  449. figsize = DEFAULTFIGURESIZE[0]*1.05, DEFAULTFIGURESIZE[1] # tweak to make space for log units
  450. linmin, linmax = 0.025, 0.2
  451. ticks = 0.05, 0.1, 0.2
  452. for kind in ['nat']:#MVIKINDS:
  453. for opto in OPTOS:
  454. f, a = plt.subplots(figsize=figsize)
  455. wintitle('runsit mean peak width movie %s %s' % (kind, opto))
  456. meanpkwruns, meanpkwsits, exmplis, exmplmseustrs, normlis = [], [], [], [], []
  457. keptmseui = 0 # manually init and increment instead of using enumerate()
  458. for mseustr in mvimseustrs:
  459. meanpkw = mviresp.loc[mseustr, kind, ST8S, opto]['meanpkw']
  460. snr = mviresp.loc[mseustr, kind, ST8S, opto]['snr']
  461. if meanpkw.isna().any(): # missing one or both values
  462. continue
  463. if (snr < SNRTHRESH).all(): # neither condition has decent SNR
  464. continue
  465. meanpkwrun, meanpkwsit = meanpkw.values
  466. meanpkwruns.append(meanpkwrun)
  467. meanpkwsits.append(meanpkwsit)
  468. fig5.loc[(mseustr, ST8S, opto), 'meanpkw'] = meanpkwrun, meanpkwsit # save
  469. if mvimseu2exmpli.get(mseustr) == fig5exmpli:
  470. exmplis.append(keptmseui)
  471. exmplmseustrs.append(mseustr)
  472. else:
  473. normlis.append(keptmseui)
  474. keptmseui += 1 # manually increment
  475. meanpkwruns = np.asarray(meanpkwruns)
  476. meanpkwsits = np.asarray(meanpkwsits)
  477. # plot y=x line:
  478. xyline = [linmin, linmax], [linmin, linmax]
  479. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  480. # plot normal (non-example) points:
  481. a.scatter(meanpkwsits[normlis], meanpkwruns[normlis], clip_on=False,
  482. marker='.', c='None', edgecolor='black', s=DEFSZ)
  483. # plot example points, one at a time:
  484. for exmpli, mseustr in zip(exmplis, exmplmseustrs):
  485. marker = exmpli2mrk[mvimseu2exmpli[mseustr]]
  486. c = exmpli2clr[mvimseu2exmpli[mseustr]]
  487. sz = exmpli2sz[mvimseu2exmpli[mseustr]]
  488. lw = exmpli2lw[mvimseu2exmpli[mseustr]]
  489. a.scatter(meanpkwsits[exmpli], meanpkwruns[exmpli], clip_on=False,
  490. marker=marker, c=c, s=sz, lw=lw)
  491. a.set_xscale('log')
  492. a.set_yscale('log')
  493. a.set_xlabel('Sit peak width (s)')
  494. a.set_ylabel('Run peak width (s)')
  495. a.set_xlim(linmin, linmax)
  496. a.set_ylim(linmin, linmax)
  497. a.set_xticks(ticks)
  498. a.set_yticks(a.get_xticks()) # make log scale y ticks the same as x ticks
  499. a.minorticks_off()
  500. axes_disable_scientific(a)
  501. a.set_aspect('equal')
  502. a.spines['left'].set_position(('outward', 4))
  503. a.spines['bottom'].set_position(('outward', 4))
  504. #t, p = ttest_rel(meanpkwsits, meanpkwruns) # paired t-test
  505. #a.add_artist(AnchoredText('p$=$%.2g' % p, loc='lower right', frameon=False))
  506. # scatter plot RMI of all movie measures vs meanrate RMI:
  507. figsize = DEFAULTFIGURESIZE
  508. linmin, linmax, linstep = -1, 1, 1
  509. ticks = np.arange(linmin, linmax+linstep, linstep)
  510. for kind in ['nat']:#MVIKINDS:
  511. for opto in [False]:#OPTOS:
  512. for measure in modmeasuresnoblank:
  513. if measure.startswith('meanrate'):
  514. continue # don't bother plotting meanrate* against meanrate
  515. axislabel = measure2axislabel[measure]
  516. rrmis, msrrmis = [], []
  517. exmplis, exmplmseustrs, normlis = [], [], []
  518. keptmseui = 0 # manually init and increment instead of using enumerate()
  519. for mseustr in mvimseustrs:
  520. rrmi = mviRMI.loc[mseustr, opto]['meanrate']
  521. msrrmi = mviRMI.loc[mseustr, opto][measure]
  522. if pd.isna(rrmi) or pd.isna(msrrmi): # missing at least one RMI value
  523. continue
  524. rrmis.append(rrmi)
  525. msrrmis.append(msrrmi)
  526. if mvimseu2exmpli.get(mseustr) == fig1exmpli:
  527. exmplis.append(keptmseui)
  528. exmplmseustrs.append(mseustr)
  529. else:
  530. normlis.append(keptmseui)
  531. keptmseui += 1 # manually increment
  532. rrmis, msrrmis = np.asarray(rrmis), np.asarray(msrrmis)
  533. assert len(rrmis) == len(msrrmis)
  534. print('%s vs meanrate: nobservations=%d' % (measure, len(rrmis)))
  535. ## scatter plot RMIs:
  536. f, a = plt.subplots(figsize=figsize)
  537. wintitle('opto RMI %s vs RMI rate %s %s' % (measure, kind, opto))
  538. # plot x=0 and y=0 lines:
  539. a.axhline(y=0, ls='--', marker='', color='lightgray', zorder=-np.inf)
  540. a.axvline(x=0, ls='--', marker='', color='lightgray', zorder=-np.inf)
  541. # plot normal (non-example) points:
  542. a.scatter(rrmis[normlis], msrrmis[normlis], clip_on=False,
  543. marker='.', c='None', edgecolor=opto2clr[opto], s=DEFSZ)
  544. # plot example points, one at a time:
  545. for exmpli, mseustr in zip(exmplis, exmplmseustrs):
  546. marker = exmpli2mrk[mvimseu2exmpli[mseustr]]
  547. c = exmpli2clr[mvimseu2exmpli[mseustr]]
  548. sz = exmpli2sz[mvimseu2exmpli[mseustr]]
  549. lw = exmpli2lw[mvimseu2exmpli[mseustr]]
  550. a.scatter(rrmis[exmpli], msrrmis[exmpli], clip_on=False,
  551. marker=marker, c=c, s=sz, lw=lw)
  552. # get fname of appropriate LMM .cvs file:
  553. if measure == 'meanburstratio': # use Steffen's LMM linregress fit, for fig5S1
  554. fname = os.path.join('stats', 'figure_5_S1c_coefs.csv')
  555. elif measure == 'spars': # use Steffen's LMM linregress fit, for fig5S1
  556. fname = os.path.join('stats', 'figure_5_S1d_coefs.csv')
  557. elif measure == 'rel': # use Steffen's LMM linregress fit, for fig5S1
  558. fname = os.path.join('stats', 'figure_5_S1e_coefs.csv')
  559. elif measure == 'snr': # use Steffen's LMM linregress fit, for fig5S1
  560. fname = os.path.join('stats', 'figure_5_S1f_coefs.csv')
  561. elif measure == 'meanpkw': # use Steffen's LMM linregress fit, for fig5S1
  562. fname = os.path.join('stats', 'figure_5_S1g_coefs.csv')
  563. else:
  564. print("WARNING: No LMM stats for %s measure" % measure)
  565. fname = None
  566. # fetch LMM linregress fit params from .csv:
  567. if fname:
  568. try:
  569. df = pd.read_csv(fname)
  570. foundregression = True
  571. except FileNotFoundError:
  572. print('Missing file: %s' % fname)
  573. foundregression = False
  574. if foundregression:
  575. mm = df['slope'][0]
  576. b = df['intercept'][0]
  577. x = np.array([rrmis.min(), rrmis.max()])
  578. y = mm * x + b
  579. a.plot(x, y, '-', color='red') # plot linregress fit
  580. a.set_xlabel('Firing rate RMI')
  581. if axislabel.islower():
  582. axislabel = axislabel.capitalize()
  583. ylabel = '%s RMI' % axislabel
  584. a.set_ylabel(ylabel)
  585. a.set_xlim(linmin, linmax)
  586. a.set_ylim(linmin, linmax)
  587. a.set_xticks(ticks)
  588. a.set_yticks(ticks)
  589. a.minorticks_off()
  590. a.set_aspect('equal')
  591. a.spines['left'].set_position(('outward', 4))
  592. a.spines['bottom'].set_position(('outward', 4))
  593. # scatter plot movie vs grating RMI for applicable measures:
  594. figsize = DEFAULTFIGURESIZE
  595. linmin, linmax, linstep = -1, 1, 1
  596. for measure in ['meanrate', 'meanburstratio']: # only 2 measures applicable to both mvi & grt
  597. axislabel = measure2axislabel[measure]
  598. for opto in OPTOS:
  599. f, a = plt.subplots(figsize=figsize)
  600. wintitle('maxRMI %s movie grating %s' % (measure, opto))
  601. mvimods, grtmods, exmplis, exmplmsustrs, normlis = [], [], [], [], []
  602. keptmsui = 0 # manually init and increment instead of using enumerate()
  603. for msustr in mvigrtmsustrs:
  604. mod = maxRMI[measure][msustr, opto]
  605. if mod.isna().any(): # missing one or both mod values
  606. continue
  607. mvimods.append(mod['mvi'])
  608. grtmods.append(mod['grt'])
  609. if msu2exmpli.get(msustr) == fig5exmpli:
  610. exmplis.append(keptmsui)
  611. exmplmsustrs.append(msustr)
  612. else:
  613. normlis.append(keptmsui)
  614. keptmsui += 1 # manually increment
  615. mvimods = np.asarray(mvimods)
  616. grtmods = np.asarray(grtmods)
  617. # plot y=x line:
  618. xyline = [linmin, linmax], [linmin, linmax]
  619. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  620. # plot normal (non-example) points:
  621. c = desat('black', opto2alpha[opto]) # do manual alpha mixing
  622. a.scatter(grtmods[normlis], mvimods[normlis], clip_on=False,
  623. marker='.', c='None', edgecolor=c, s=DEFSZ)
  624. # plot example points, one at a time:
  625. for exmpli, msustr in zip(exmplis, exmplmsustrs):
  626. marker = exmpli2mrk[msu2exmpli[msustr]]
  627. c = exmpli2clr[msu2exmpli[msustr]]
  628. sz = exmpli2sz[msu2exmpli[msustr]]
  629. lw = exmpli2lw[msu2exmpli[msustr]]
  630. a.scatter(grtmods[exmpli], mvimods[exmpli], clip_on=False,
  631. marker=marker, c=c, s=sz, lw=lw)
  632. a.set_xlabel('Grating %s RMI' % axislabel)
  633. a.set_ylabel('Movie %s RMI' % axislabel)
  634. a.set_xlim(linmin, linmax)
  635. a.set_ylim(linmin, linmax)
  636. a.set_xticks(np.arange(linmin, linmax+linstep, linstep))
  637. a.set_yticks(a.get_xticks()) # make log scale y ticks the same as x ticks
  638. a.minorticks_off()
  639. a.set_aspect('equal')
  640. a.spines['left'].set_position(('outward', 4))
  641. a.spines['bottom'].set_position(('outward', 4))
  642. #t, p = ttest_rel(grtmods, mvimods) # paired t-test
  643. #a.add_artist(AnchoredText('$\mathregular{p=%.2g}$' % p,
  644. # loc='upper left', frameon=False))