fig4.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. """Figure 4 and some 4S1 plots, use run -i fig4.py"""
  2. mvimeasures = ['meanrate', 'meanrate02', 'meanrate35', 'blankmeanrate',
  3. 'meanburstratio', 'blankmeanburstratio']
  4. grtmeasures = ['meanrate', 'meanrate', 'meanrate', 'blankmeanrate',
  5. 'meanburstratio', 'blankmeanburstratio']
  6. mi = pd.MultiIndex.from_product([mvigrtmsustrs, STIMTYPES, [False, 'prestim', 'cond']],
  7. names=['msu', 'stimtype', 'blank'])
  8. fig4 = pd.DataFrame(index=mi, columns=['meanrate', 'meanburstratio'])
  9. ## NOTE: make sure that rows are not overwritten due to temporarily enabling iteration
  10. ## over st8 in any of the following loops!
  11. # strip, scatter and dumbbell plot movie vs grating FMI for applicable measures:
  12. np.random.seed(0) # to get identical horizontal jitter in strip plots on every run
  13. figsize = DEFAULTFIGURESIZE
  14. linmin, linmax, linstep = -1, 1, 1
  15. ticks = np.arange(linmin, linmax+linstep, linstep)
  16. for mvimeasure, grtmeasure in zip(mvimeasures, grtmeasures):
  17. measure = mvimeasure
  18. isblank = mvimeasure.startswith('blank')
  19. if isblank:
  20. measure = mvimeasure.split('blank')[1]
  21. axislabel = measure2axislabel[mvimeasure]
  22. axislabel = short2longaxislabel.get(axislabel, axislabel)
  23. if axislabel[0].islower():
  24. Axislabel = axislabel.capitalize()
  25. else:
  26. Axislabel = axislabel
  27. for st8 in ['none']:#ALLST8S:
  28. #mvifmis, grtfmis = [], []
  29. mvimaxfmis, grtmaxfmis, grtmaxfmi2s = [], [], []
  30. exmplis, exmplmsustrs, normlis = [], [], []
  31. # collect all movie FMIs:
  32. '''
  33. for mseustr in mvimseustrs:
  34. mvifmi = mviFMI[mvimeasure][mseustr, st8]
  35. if pd.isna(mvifmi):
  36. continue
  37. mvifmis.append(mvifmi)
  38. # collect all grating FMIs:
  39. for mseustr in grtmseustrs:
  40. grtfmi = grtFMI[grtmeasure][mseustr, st8]
  41. if pd.isna(grtfmi):
  42. continue
  43. grtfmis.append(grtfmi)
  44. '''
  45. # collect paired movie and grating max FMIs:
  46. keptmsui = 0
  47. for msustr in mvigrtmsustrs:
  48. mvimaxfmi = maxFMI[mvimeasure][msustr, st8, 'mvi']
  49. grtmaxfmi = maxFMI[grtmeasure][msustr, st8, 'grt']
  50. '''
  51. ## hack to replicate Steffen's code in R:
  52. if mvimeasure == 'meanrate':
  53. othermvimaxfmi = maxFMI['meanburstratio'][msustr, st8, 'mvi']
  54. othergrtmaxfmi = maxFMI['meanburstratio'][msustr, st8, 'grt']
  55. if pd.isna(othermvimaxfmi) or pd.isna(othergrtmaxfmi):
  56. continue
  57. '''
  58. if pd.isna(mvimaxfmi) or pd.isna(grtmaxfmi): # missing one or both maxFMI values
  59. continue
  60. if isblank: # add a second grtmaxfmi measure for blank cond
  61. blankname = 'blankcond' + measure
  62. grtmaxfmi2 = maxFMI[blankname][msustr, st8, 'grt']
  63. if pd.isna(grtmaxfmi2):
  64. continue
  65. else:
  66. grtmaxfmi2s.append(grtmaxfmi2)
  67. mvimaxfmis.append(mvimaxfmi)
  68. grtmaxfmis.append(grtmaxfmi)
  69. if measure in fig4.columns:
  70. assert mvimeasure == grtmeasure
  71. if isblank: # save both kinds of grt blank measures
  72. fig4.loc[msustr, 'mvi', 'prestim'][measure] = mvimaxfmi # save
  73. fig4.loc[msustr, 'grt', 'prestim'][measure] = grtmaxfmi # save
  74. fig4.loc[msustr, 'grt', 'cond'][measure] = grtmaxfmi2 # save
  75. else:
  76. fig4.loc[msustr, 'mvi', False][measure] = mvimaxfmi # save
  77. fig4.loc[msustr, 'grt', False][measure] = grtmaxfmi # save
  78. #if grtmeasure == 'meanburstratio' and grtmaxfmi > 0.8:
  79. # print('OUTLIER: %s grtmaxfmi=%g' % (msustr, grtmaxfmi))
  80. if msustr in msu2exmpli:
  81. exmplis.append(keptmsui)
  82. exmplmsustrs.append(msustr)
  83. else:
  84. normlis.append(keptmsui)
  85. keptmsui += 1 # manually increment
  86. #mvifmis = np.asarray(mvifmis)
  87. #grtfmis = np.asarray(grtfmis)
  88. mvimaxfmis = np.asarray(mvimaxfmis)
  89. grtmaxfmis = np.asarray(grtmaxfmis)
  90. grtmaxfmi2s = np.asarray(grtmaxfmi2s)
  91. assert len(mvimaxfmis) == len(grtmaxfmis)
  92. npairs = len(mvimaxfmis)
  93. '''
  94. ## strip plot movie and grating FMIs, for all mseus:
  95. f, a = plt.subplots(figsize=figsize)
  96. wintitle('FMI %s nat movie grating stripplot %s' % (mvimeasure, st8))
  97. # plot y=0 line:
  98. a.axhline(y=0, ls='--', marker='', color='lightgray', zorder=-np.inf)
  99. data = pd.DataFrame(data={'stimtype':['Movie']*len(mvifmis)+['Grating']*len(grtfmis),
  100. 'FMI':np.concatenate([mvifmis, grtfmis])})
  101. sns.stripplot(x='stimtype', y='FMI', data=data, jitter=True, clip_on=False,
  102. marker='.', color='None', edgecolor=st82clr[st8], size=np.sqrt(50))
  103. # exclude extreme +/- 1 FMI values from mean and ttest:
  104. #mvifmisnon1 = mvifmis[abs(mvifmis) != 1]
  105. #grtfmisnon1 = grtfmis[abs(grtfmis) != 1]
  106. # plot mean with short horizontal lines:
  107. #meanmvifmi, meangrtfmi = mvifmisnon1.mean(), grtfmisnon1.mean()
  108. #a.plot([-0.25, 0.25], [meanmvifmi, meanmvifmi], '-', lw=2, c='red', zorder=np.inf)
  109. #a.plot([0.75, 1.25], [meangrtfmi, meangrtfmi], '-', lw=2, c='red', zorder=np.inf)
  110. a.set_xlabel('')
  111. a.set_ylabel('%s FMI' % Axislabel)
  112. a.set_ylim(-1, 1)
  113. t, p = ttest_ind(mvifmisnon1, grtfmisnon1, equal_var=False) # non-paired t-test
  114. a.add_artist(AnchoredText('p$=$%.2g' % p, loc='upper center', frameon=False))
  115. # connect the dots:
  116. x = np.array([[0]*npairs, [1]*npairs])
  117. y = np.array([mvimaxfmis, grtmaxfmis])
  118. a.plot(x, y, '-', c='k', alpha=0.2, lw=1)
  119. # due to jitter, dots don't perfectly connect. Can get actual data using:
  120. #mvixy, grtxy = a.collections[0].get_offsets(), a.collections[1].get_offsets()
  121. # but some of those points aren't paired, which makes it complicated
  122. '''
  123. ## strip plot paired movie and grating max FMIs:
  124. if mvimeasure == 'meanrate': # 2 column wide strip plot
  125. f, a = plt.subplots(figsize=(figsize[0]*1.35, figsize[1]*1.5))
  126. elif mvimeasure == 'blankmeanrate': # 3 column wide strip plot
  127. f, a = plt.subplots(figsize=(figsize[0]*1.9, figsize[1]*1.5))
  128. elif mvimeasure == 'blankmeanburstratio': # 3 column normal width strip plot
  129. f, a = plt.subplots(figsize=(figsize[0]*1.4, figsize[1]))
  130. else:
  131. f, a = plt.subplots(figsize=figsize)
  132. wintitle('maxFMI %s movie grating stripplot' % mvimeasure)
  133. # plot y=0 line:
  134. a.axhline(y=0, ls='--', marker='', color='lightgray', zorder=-np.inf)
  135. datad = {'Movie':mvimaxfmis, 'Grating':grtmaxfmis}
  136. if isblank:
  137. datad = {'Movie':mvimaxfmis, 'Grating':grtmaxfmis,
  138. 'GratingCond':grtmaxfmi2s}
  139. data = pd.DataFrame.from_dict(datad, orient='index').transpose()
  140. sns.stripplot(ax=a, data=data, clip_on=False, marker='.',
  141. color='None', edgecolor='black', size=np.sqrt(50))
  142. # get fname of appropriate LMM .cvs file:
  143. if mvimeasure == 'meanrate' and grtmeasure == 'meanrate':
  144. fname = os.path.join('stats', 'figure_4a_pred_means.csv')
  145. elif mvimeasure == 'blankmeanrate' and grtmeasure == 'blankmeanrate':
  146. fname = os.path.join('stats', 'figure_4b_pred_means.csv')
  147. elif mvimeasure == 'meanburstratio' and grtmeasure == 'meanburstratio':
  148. fname = os.path.join('stats', 'figure_4_S1e_pred_means.csv')
  149. elif mvimeasure == 'blankmeanburstratio' and grtmeasure == 'blankmeanburstratio':
  150. fname = os.path.join('stats', 'figure_4_S1f_pred_means.csv')
  151. else:
  152. print("WARNING: No LMM stats for (mvimeasure=%s, grtmeasure=%s)"
  153. % (mvimeasure, grtmeasure))
  154. fname = None
  155. if fname:
  156. try:
  157. df = pd.read_csv(fname)
  158. foundregression = True
  159. except FileNotFoundError:
  160. print('Missing file: %s' % fname)
  161. foundregression = False
  162. if foundregression:
  163. # fetch LMM means from .csv:
  164. meanmvimaxfmi = df['mvi'][0]
  165. meangrtmaxfmi = df['grt'][0]
  166. # plot mean with short horizontal lines:
  167. a.plot([-0.25, 0.25], [meanmvimaxfmi, meanmvimaxfmi], '-', lw=2, c='red',
  168. zorder=np.inf)
  169. a.plot([0.75, 1.25], [meangrtmaxfmi, meangrtmaxfmi], '-', lw=2, c='red',
  170. zorder=np.inf)
  171. if isblank:
  172. meangrtmaxfmi2 = df['grt0c'][0]
  173. a.plot([1.75, 2.25], [meangrtmaxfmi2, meangrtmaxfmi2], '-', lw=2, c='red',
  174. zorder=np.inf)
  175. a.set_ylabel('%s FMI' % Axislabel)
  176. #if measure.startswith('meanrate'):
  177. # a.set_ylim(-0.6, 1)
  178. # a.set_yticks([-0.5, 0, 0.5, 1])
  179. #else:
  180. a.set_ylim(-1, 1)
  181. a.set_yticks([-1, -0.5, 0, 0.5, 1])
  182. a.spines['bottom'].set_position(('outward', 5))
  183. a.spines['bottom'].set_visible(False)
  184. a.tick_params(bottom=False)
  185. # connect the dots:
  186. if isblank:
  187. x = np.array([[0]*npairs, [1]*npairs, [2]*npairs])
  188. y = np.array([mvimaxfmis, grtmaxfmis, grtmaxfmi2s])
  189. else:
  190. x = np.array([[0]*npairs, [1]*npairs])
  191. y = np.array([mvimaxfmis, grtmaxfmis])
  192. signs = np.sign(y)
  193. nonsignchangeis = signs[0] == signs[1]
  194. posslopeis = (signs[0] < 0) & (signs[1] > 0)
  195. negslopeis = (signs[0] > 0) & (signs[1] < 0)
  196. #signchangeis = signs[0] != signs[1]
  197. a.plot(x[:, nonsignchangeis], y[:, nonsignchangeis], '-', c='k', alpha=0.2, lw=1)
  198. a.plot(x[:, posslopeis], y[:, posslopeis], '--', c='k', alpha=1.0, lw=1)
  199. a.plot(x[:, negslopeis], y[:, negslopeis], '-', c='k', alpha=1.0, lw=1)
  200. #a.plot(x[:, signchangeis], y[:, signchangeis], '-', c='k', alpha=1.0, lw=1)
  201. # due to jitter, dots don't perfectly connect. Can get actual data using:
  202. #mvixy, grtxy = a.collections[0].get_offsets(), a.collections[1].get_offsets()
  203. ## scatter plot movie vs. grating max FMIs:
  204. '''
  205. f, a = plt.subplots(figsize=figsize)
  206. wintitle('maxFMI %s movie grating scatter' % mvimeasure)
  207. # plot x=0 and y=0 lines:
  208. a.axhline(y=0, ls='--', marker='', color='lightgray', zorder=-np.inf)
  209. a.axvline(x=0, ls='--', marker='', color='lightgray', zorder=-np.inf)
  210. # plot y=x line:
  211. xyline = [linmin, linmax], [linmin, linmax]
  212. a.plot(xyline[0], xyline[1], '--', color='gray', zorder=-1)
  213. # plot normal (non-example) points:
  214. a.scatter(grtmaxfmis[normlis], mvimaxfmis[normlis], clip_on=False,
  215. marker='.', c='None', edgecolor=st82clr[st8], s=DEFSZ)
  216. # plot example points, one at a time:
  217. for exmpli, msustr in zip(exmplis, exmplmsustrs):
  218. marker = exmpli2mrk[msu2exmpli[msustr]]
  219. c = exmpli2clr[msu2exmpli[msustr]]
  220. sz = exmpli2sz[msu2exmpli[msustr]]
  221. lw = exmpli2lw[msu2exmpli[msustr]]
  222. a.scatter(grtmaxfmis[exmpli], mvimaxfmis[exmpli], marker=marker, c=c, s=sz, lw=lw)
  223. # exclude extreme +/- 1 FMI values from mean and ttest:
  224. non1is = (abs(grtmaxfmis) != 1) & (abs(mvimaxfmis) != 1)
  225. grtmaxfmisnon1 = grtmaxfmis[non1is]
  226. mvimaxfmisnon1 = mvimaxfmis[non1is]
  227. # plot mean:
  228. a.scatter(np.mean(grtmaxfmisnon1), np.mean(mvimaxfmisnon1),
  229. c='red', edgecolor='red', s=50, marker='^')
  230. a.set_xlabel('Grating %s FMI' % axislabel)
  231. a.set_ylabel('Movie %s FMI' % axislabel)
  232. a.set_xlim(linmin, linmax)
  233. a.set_ylim(linmin, linmax)
  234. a.set_xticks(ticks)
  235. a.set_yticks(a.get_xticks()) # make log scale y ticks the same as x ticks
  236. a.minorticks_off()
  237. a.set_aspect('equal')
  238. a.spines['left'].set_position(('outward', 4))
  239. a.spines['bottom'].set_position(('outward', 4))
  240. t, p = ttest_rel(grtmaxfmisnon1, mvimaxfmisnon1) # paired t-test
  241. a.add_artist(AnchoredText('p$=$%.2g' % p, loc='lower right', frameon=False))
  242. '''
  243. ## dumbbell plot:
  244. '''
  245. f, a = plt.subplots(figsize=DUMBBELLFIGSIZE)
  246. wintitle('maxFMI %s movie grating dumbbell' % mvimeasure)
  247. # plot x=0 line:
  248. a.axvline(x=0, ls='--', marker='', color='lightgray', zorder=-np.inf)
  249. # plot horizontal lines:
  250. mvimaxfmisortis = mvimaxfmis.argsort() # y vals for hlines
  251. npairs = len(mvimaxfmis)
  252. ys = np.arange(npairs)
  253. xmvis, xgrts = mvimaxfmis[mvimaxfmisortis], grtmaxfmis[mvimaxfmisortis]
  254. a.hlines(ys, xmvis, xgrts, zorder=-100)
  255. sz = 100
  256. # plot grt points:
  257. a.scatter(xgrts, ys, clip_on=False, marker='.', c='white',
  258. edgecolor=st82clr[st8], s=sz)
  259. # plot mvi points:
  260. a.scatter(xmvis, ys, clip_on=False, marker='.', c=st82clr[st8], s=sz)
  261. a.set_xlabel('%s FMI' % Axislabel)
  262. a.set_ylabel('Neurons')
  263. a.set_xlim(linmin, linmax)
  264. a.set_ylim(-1, npairs)
  265. a.set_xticks(ticks)
  266. a.set_yticks([])
  267. a.spines['left'].set_position(('outward', 4))
  268. a.spines['left'].set_visible(False)
  269. '''
  270. '''
  271. # plot CDFs of spatial suppression index for blankscreen movies/gratings wrt full screen
  272. # movies/gratings, for meanrate and meanburstratio, for control and opto conditions:
  273. figsize = DEFAULTFIGURESIZE
  274. stimtype2resp = {'mvi':mviresp, 'grt':grtresp}
  275. for stimtype in ['mvi', 'grt']:
  276. resp = stimtype2resp[stimtype]
  277. if stimtype == 'mvi':
  278. resp = resp.xs('nat', level='kind') # dereference movie 'kind' index level
  279. for measure in ['meanrate', 'meanburstratio']:
  280. f, a = plt.subplots(figsize=figsize)
  281. wintitle('SSI %s %s blank vs fullscreen CDF' % (stimtype, measure))
  282. opto2SSI = {}
  283. for opto in OPTOS:
  284. rows = resp.xs(['none', opto], level=['st8', 'opto']) # only mseu index left
  285. fullscreen = rows[measure]
  286. blank = rows['blank'+measure]
  287. SSI = (blank - fullscreen) / (blank + fullscreen)
  288. SSI = np.float64(SSI[SSI.notna()].values) # pull float array out of object Series
  289. opto2SSI[opto] = SSI
  290. SSIbins = list(np.unique(SSI)) + [10]
  291. fb = opto2fb[opto].capitalize()
  292. a.hist(SSI, bins=SSIbins, density=True, histtype='step',
  293. cumulative=True, clip_on=True, lw=1.5,
  294. label=fb, color=opto2clr[opto], alpha=1)
  295. a.set_xlabel('Spatial suppression index')
  296. a.set_ylabel('Cumulative probability')
  297. #a.legend(frameon=False)
  298. a.set_xlim(-1, 1)
  299. a.set_ylim(0, 1.01)
  300. a.set_yticks([0, 0.5, 1])
  301. #a.spines['left'].set_position(('outward', 4))
  302. _, KS_p = ks_2samp(opto2SSI[False], opto2SSI[True])
  303. txt = '$\mathregular{p_{KS}=%.2g}$' % KS_p # prob that distribs are the same
  304. a.add_artist(AnchoredText(txt, loc='lower right', frameon=False))
  305. # stripplot spatial suppression index for blankscreen movies/gratings wrt full screen
  306. # movies/gratings, for meanrate and meanburstratio, for both opto conditions, for all mseu:
  307. figsize = DEFAULTFIGURESIZE
  308. stimtype2resp = {'mvi':mviresp, 'grt':grtresp}
  309. for measure in ['meanrate', 'meanburstratio']:
  310. opto2SSI = {}
  311. for stimtype in ['mvi', 'grt']:
  312. resp = stimtype2resp[stimtype]
  313. if stimtype == 'mvi':
  314. resp = resp.xs('nat', level='kind') # dereference movie 'kind' index level
  315. for opto in OPTOS:
  316. rows = resp.xs(['none', opto], level=['st8', 'opto']) # only mseu index left
  317. fullscreen = rows[measure]
  318. blank = rows['blank'+measure]
  319. SSI = (blank - fullscreen) / (blank + fullscreen)
  320. #SSI = (blank - fullscreen) / blank
  321. SSI = np.float64(SSI[SSI.notna()].values) # pull float array out of object Series
  322. opto2SSI[opto] = SSI
  323. # stripplot:
  324. SSIons, SSIoffs = opto2SSI[True], opto2SSI[False]
  325. f, a = plt.subplots(figsize=figsize)
  326. wintitle('SSI %s %s blank vs fullscreen stripplot' % (stimtype, measure))
  327. data = pd.DataFrame.from_dict({'Feedback':SSIoffs, 'Suppression':SSIons},
  328. orient='index').transpose()
  329. sns.stripplot(ax=a, data=data, clip_on=False, marker='.',
  330. color='None', edgecolor='black', size=np.sqrt(50))
  331. # exclude extreme +/- 1 SSI values from mean:
  332. SSIonsnon1 = SSIons[abs(SSIons) != 1]
  333. SSIoffsnon1 = SSIoffs[abs(SSIoffs) != 1]
  334. # plot mean with short horizontal lines:
  335. meanSSIon, meanSSIoff = SSIonsnon1.mean(), SSIoffsnon1.mean()
  336. a.plot([-0.25, 0.25], [meanSSIoff, meanSSIoff], '-', lw=2, c='red', zorder=np.inf)
  337. a.plot([0.75, 1.25], [meanSSIon, meanSSIon], '-', lw=2, c='red', zorder=np.inf)
  338. a.set_ylabel('Spatial suppression index')
  339. a.set_ylim(-1, 1)
  340. a.spines['bottom'].set_position(('outward', 5))
  341. a.spines['bottom'].set_visible(False)
  342. a.tick_params(bottom=False)
  343. # stripplot FMI spatial suppression index for blankscreen movies/gratings wrt full screen
  344. # movies/gratings, for meanrate and meanburstratio, for all mseu:
  345. figsize = DEFAULTFIGURESIZE
  346. stimtype2FMI = {'mvi':mviFMI, 'grt':grtFMI}
  347. for measure in ['meanrate', 'meanburstratio']:
  348. stimtype2SSI = {}
  349. for stimtype in ['mvi', 'grt']:
  350. FMI = stimtype2FMI[stimtype]
  351. rows = FMI.xs('none', level='st8') # only mseu index left
  352. fullscreen = rows[measure]
  353. blank = rows['blank'+measure]
  354. SSI = (blank - fullscreen) / (abs(blank) + abs(fullscreen))
  355. #SSI = (blank - fullscreen) / blank
  356. SSI = np.float64(SSI[SSI.notna()].values) # pull float array out of object Series
  357. stimtype2SSI[stimtype] = SSI
  358. # plot CDF:
  359. f, a = plt.subplots(figsize=figsize)
  360. wintitle('SSI %s %s FMI blank vs fullscreen' % (stimtype, measure))
  361. SSIbins = list(np.unique(SSI)) + [10]
  362. a.hist(SSI, bins=SSIbins, density=True, histtype='step',
  363. cumulative=True, clip_on=True, lw=1.5, color='black', alpha=1)
  364. a.set_xlabel('FMI spatial suppression index')
  365. a.set_ylabel('Cumulative probability')
  366. #a.legend(frameon=False)
  367. a.set_xlim(-1, 1)
  368. a.set_ylim(0, 1.01)
  369. a.set_yticks([0, 0.5, 1])
  370. #a.spines['left'].set_position(('outward', 4))
  371. # stripplot:
  372. mviSSI, grtSSI = stimtype2SSI['mvi'], stimtype2SSI['grt']
  373. f, a = plt.subplots(figsize=figsize)
  374. wintitle('SSI %s FMI blank vs fullscreen stripplot' % measure)
  375. data = pd.DataFrame.from_dict({'Movie':mviSSI, 'Grating':grtSSI},
  376. orient='index').transpose()
  377. sns.stripplot(ax=a, data=data, clip_on=False, marker='.',
  378. color='None', edgecolor='black', size=np.sqrt(50))
  379. # exclude extreme +/- 1 SSI values from mean:
  380. mviSSInon1 = mviSSI[abs(mviSSI) != 1]
  381. grtSSInon1 = grtSSI[abs(grtSSI) != 1]
  382. # plot mean with short horizontal lines:
  383. meanmvifmi, meangrtfmi = mviSSInon1.mean(), grtSSInon1.mean()
  384. a.plot([-0.25, 0.25], [meanmvifmi, meanmvifmi], '-', lw=2, c='red', zorder=np.inf)
  385. a.plot([0.75, 1.25], [meangrtfmi, meangrtfmi], '-', lw=2, c='red', zorder=np.inf)
  386. a.set_ylabel('FMI spatial suppression index')
  387. a.set_ylim(-1, 1)
  388. a.spines['bottom'].set_position(('outward', 5))
  389. a.spines['bottom'].set_visible(False)
  390. a.tick_params(bottom=False)
  391. # dumbbell plot FMI spatial suppression index for blankscreen movies/gratings wrt full screen
  392. # movies/gratings, for meanrate and meanburstratio, for all mseu:
  393. figsize = DEFAULTFIGURESIZE
  394. for measure in ['meanrate', 'meanburstratio']:
  395. stimtype2SSI = {}
  396. for stimtype in ['mvi', 'grt']:
  397. rows = maxFMI.xs(['none', stimtype], level=['st8', 'stimtype']) # only msu index left
  398. fullscreen = rows[measure]
  399. blank = rows['blank'+measure]
  400. SSI = (blank - fullscreen) / (abs(blank) + abs(fullscreen))
  401. #SSI = (blank - fullscreen) / blank
  402. SSI = np.float64(SSI.values) # pull float array out of object Series
  403. stimtype2SSI[stimtype] = SSI
  404. mviSSI, grtSSI = stimtype2SSI['mvi'], stimtype2SSI['grt']
  405. keepis = pd.notna(mviSSI) & pd.notna(grtSSI) # remove any unit that has NaN in either stim
  406. mviSSI, grtSSI = mviSSI[keepis], grtSSI[keepis]
  407. f, a = plt.subplots(figsize=figsize)
  408. wintitle('SSI %s maxFMI blank vs fullscreen stripplot dumbbell' % measure)
  409. # plot x=0 line:
  410. a.axvline(x=0, ls='--', marker='', color='lightgray', zorder=-np.inf)
  411. # plot horizontal lines:
  412. mviSSIsortis = mviSSI.argsort() # y vals for hlines
  413. npairs = len(mviSSI)
  414. ys = np.arange(npairs)
  415. xmvis, xgrts = mviSSI[mviSSIsortis], grtSSI[mviSSIsortis]
  416. a.hlines(ys, xmvis, xgrts, zorder=-100)
  417. sz = 100
  418. # plot grt points:
  419. a.scatter(xgrts, ys, marker='.', c='white', edgecolor=st82clr[st8], s=sz)
  420. # plot mvi points:
  421. a.scatter(xmvis, ys, marker='.', c=st82clr[st8], s=sz)
  422. axislabel = measure2axislabel[measure]
  423. if axislabel[0].islower():
  424. Axislabel = axislabel.capitalize()
  425. else:
  426. Axislabel = axislabel
  427. a.set_xlabel('%s FMI SSI' % Axislabel)
  428. a.set_ylabel('Neurons')
  429. #a.set_xlim(linmin-eps, linmax+eps)
  430. a.set_ylim(-1, npairs)
  431. #a.set_xticks(ticks)
  432. a.set_yticks([])
  433. '''