@@ -71,8 +71,9 @@ def get_chreef_data():
7171 chreef_data [cochlea ] = values
7272
7373 with open (cache_path , "wb" ) as f :
74- chreef_data = pickle .dump (chreef_data , f )
75- return chreef_data
74+ pickle .dump (chreef_data , f )
75+ with open (cache_path , "rb" ) as f :
76+ return pickle .load (f )
7677
7778
7879def group_lr (names_lr , values ):
@@ -143,7 +144,7 @@ def fig_04c(chreef_data, save_path, plot=False, plot_by_side=False):
143144 plt .xlim (xmin , xmax )
144145 lower_y , upper_y = literature_reference_values ("SGN" )
145146 plt .hlines ([lower_y , upper_y ], xmin , xmax )
146- plt .text (1 , lower_y - 400 , "literature" , color = "C0" , fontsize = main_tick_size , ha = "center" )
147+ plt .text (1.5 , lower_y - 400 , "literature" , color = "C0" , fontsize = main_tick_size , ha = "center" )
147148 plt .fill_between ([xmin , xmax ], lower_y , upper_y , color = "C0" , alpha = 0.05 , interpolate = True )
148149
149150 sgn_values = [11153 , 11398 , 10333 , 11820 ]
@@ -154,12 +155,12 @@ def fig_04c(chreef_data, save_path, plot=False, plot_by_side=False):
154155 lower_y = sgn_value - 1.96 * sgn_std
155156
156157 plt .hlines ([lower_y , upper_y ], xmin , xmax , colors = ["C1" for _ in range (2 )])
157- plt .text (1 , upper_y + 100 , "healthy cochleae (95% confidence interval)" ,
158+ plt .text (1.5 , upper_y + 100 , "healthy cochleae (95% confidence interval)" ,
158159 color = "C1" , fontsize = main_tick_size , ha = "center" )
159160 plt .fill_between ([xmin , xmax ], lower_y , upper_y , color = "C1" , alpha = 0.05 , interpolate = True )
160161
161- plt .savefig (save_path , bbox_inches = "tight" , pad_inches = 0.1 , dpi = png_dpi )
162162 plt .tight_layout ()
163+ plt .savefig (save_path , bbox_inches = "tight" , pad_inches = 0.1 , dpi = png_dpi )
163164
164165 if plot :
165166 plt .show ()
@@ -179,12 +180,10 @@ def fig_04d(chreef_data, save_path, plot=False, plot_by_side=False, intensity=Fa
179180 intensities = vals ["median" ].values
180181 values .append (intensities .mean ())
181182 else :
182- # The marker labels don't make sense yet, they are in
183- # 0: unlabeled
183+ # marker labels
184+ # 0: unlabeled - no median intensity in object_measures table
184185 # 1: positive
185186 # 2: negative
186- # but they should all be either positive or negative.
187- # Or am I missing something?
188187 marker_labels = vals ["marker_labels" ].values
189188 n_pos = (marker_labels == 1 ).sum ()
190189 n_neg = (marker_labels == 2 ).sum ()
@@ -222,8 +221,8 @@ def fig_04d(chreef_data, save_path, plot=False, plot_by_side=False, intensity=Fa
222221 if not intensity :
223222 plt .ylim (0.5 , 1.05 )
224223
225- plt .savefig (save_path , bbox_inches = "tight" , pad_inches = 0.1 , dpi = png_dpi )
226224 plt .tight_layout ()
225+ plt .savefig (save_path , bbox_inches = "tight" , pad_inches = 0.1 , dpi = png_dpi )
227226
228227 if plot :
229228 plt .show ()
@@ -255,30 +254,76 @@ def fig_04e(chreef_data, save_path, plot, intensity=False):
255254 band_to_x = {band : i for i , band in enumerate (bin_labels )}
256255 result ["x_pos" ] = result ["octave_band" ].map (band_to_x )
257256
258- fig , axes = plt .subplots (1 , 2 , figsize = (8 , 4 ), sharex = True , sharey = True )
257+ fig , ax = plt .subplots (figsize = (8 , 4 ))
258+
259+ sub_tick_label_size = 8
260+ tick_label_size = 12
261+ label_size = 12
262+ legend_size = 8
263+ if intensity :
264+ band_label_offset_y = 0.09
265+ else :
266+ band_label_offset_y = 0.07
267+ ax .set_ylim (0.45 , 1.05 )
268+
269+ # Offsets within each octave band
270+ offset_map = {"L" : - 0.15 , "R" : 0.15 }
271+ sublabels = {"L" : "L" , "R" : "R" }
272+
273+ # Assign a color to each cochlea (ignoring side)
274+ cochleas = sorted ({name_lr [:- 1 ] for name_lr in result ["cochlea" ].unique ()})
275+ colors = plt .cm .tab10 .colors # pick a colormap
276+ color_map = {cochlea : colors [i % len (colors )] for i , cochlea in enumerate (cochleas )}
277+
278+ # Track which cochlea names we have already added to the legend
279+ legend_added = set ()
280+
281+ all_x_positions = []
282+ all_x_labels = []
283+
259284 for name_lr , grp in result .groupby ("cochlea" ):
260285 name , side = name_lr [:- 1 ], name_lr [- 1 ]
261- ax , marker = (axes [0 ], "o" ) if side == "L" else (axes [1 ], "x" )
262- ax .scatter (grp ["x_pos" ], grp ["value" ], label = name , s = 60 , alpha = 0.8 , marker = marker )
263-
264- for ax in axes :
265- ax .set_xticks (range (len (bin_labels )))
266- ax .set_xticklabels (bin_labels )
267- ax .set_xlabel ("Octave band (kHz)" )
286+ x_positions = grp ["x_pos" ] + offset_map [side ]
287+ ax .scatter (
288+ x_positions ,
289+ grp ["value" ],
290+ label = name if name not in legend_added else None ,
291+ s = 60 ,
292+ alpha = 0.8 ,
293+ marker = "o" if side == "L" else "x" ,
294+ color = color_map [name ]
295+ )
296+ if name not in legend_added :
297+ legend_added .add (name )
298+
299+ # Store for sublabel ticks
300+ all_x_positions .extend (x_positions )
301+ all_x_labels .extend ([sublabels [side ]] * len (x_positions ))
302+
303+ # Create combined tick positions & labels
304+ main_ticks = range (len (bin_labels ))
305+ # add a final tick for label '>64k'
306+ ax .set_xticks ([pos + offset_map ["L" ] for pos in main_ticks [:- 1 ]] +
307+ [pos + offset_map ["R" ] for pos in main_ticks [:- 1 ]] +
308+ [pos for pos in main_ticks [- 1 :]])
309+ ax .set_xticklabels (["L" ] * len (main_ticks [:- 1 ]) + ["R" ] * len (main_ticks [:- 1 ]) + ["" ], fontsize = sub_tick_label_size )
310+
311+ # Add main octave band labels above sublabels
312+ for i , label in enumerate (bin_labels ):
313+ ax .text (i , ax .get_ylim ()[0 ] - band_label_offset_y * (ax .get_ylim ()[1 ]- ax .get_ylim ()[0 ]),
314+ label , ha = 'center' , va = 'top' , fontsize = tick_label_size , fontweight = 'bold' )
315+
316+ ax .set_xlabel ("Octave band (kHz)" , fontsize = label_size )
317+ ax .xaxis .set_label_coords (.5 , - .16 )
268318
269319 if intensity :
270- axes [0 ].set_ylabel ("Marker Intensity" )
271- for ax , side in zip (axes , ("Left" , "Right" )):
272- ax .set_title (f"Intensity per octave band ({ side } )" )
320+ ax .set_ylabel ("Marker Intensity" , fontsize = label_size )
321+ ax .set_title ("Intensity per octave band (Left/Right)" )
273322 else :
274- axes [0 ].set_ylabel ("Transduction Efficiency" )
275- axes [0 ].set_ylim (0.5 , 1.05 )
276- for ax , side in zip (axes , ("Left" , "Right" )):
277- ax .set_title (f"Transduction efficiency per octave band ({ side } )" )
278-
279- # FIXME make this uniform across the plots!
280- axes [0 ].legend (title = "Cochlea" )
281- axes [1 ].legend (title = "Cochlea" )
323+ ax .set_ylabel ("Transduction Efficiency" , fontsize = label_size )
324+ ax .set_title ("Transduction efficiency per octave band (Left/Right)" )
325+
326+ ax .legend (title = "Cochlea" , fontsize = legend_size )
282327 plt .tight_layout ()
283328
284329 plt .savefig (save_path , bbox_inches = "tight" , pad_inches = 0.1 , dpi = png_dpi )
0 commit comments