@@ -161,9 +161,11 @@ def _layers(self):
161
161
def data (self ):
162
162
"""Return a pandas Series representing the profile."""
163
163
self ._check_sanity ()
164
- return pd .DataFrame (
165
- self ._values , index = self ._depths , columns = [f"{ self .modality } ({ self .unit } )" ]
166
- )
164
+ if self ._values .shape [1 ] == 2 :
165
+ columns = [f"{ self .modality } mean ({ self .unit } )" , "std" ]
166
+ else :
167
+ columns = [f"{ self .modality } ({ self .unit } )" ]
168
+ return pd .DataFrame (self ._values , index = self ._depths , columns = columns )
167
169
168
170
@classmethod
169
171
def _merge_elements (
@@ -175,12 +177,13 @@ def _merge_elements(
175
177
):
176
178
assert all (np .array_equal (elements [0 ]._depths , f ._depths ) for f in elements )
177
179
assert len ({f .unit for f in elements }) == 1
180
+ values_stacked = np .stack ([f ._values for f in elements ])
178
181
return CorticalProfile (
179
182
description = description ,
180
183
modality = modality ,
181
184
anchor = anchor ,
182
- depths = elements [ 0 ] ._depths ,
183
- values = np .stack ([f . _values for f in elements ]). mean (0 ),
185
+ depths = np . stack ([ f ._depths for f in elements ]). mean ( 0 ) ,
186
+ values = np .stack ([values_stacked . mean ( 0 ), values_stacked . std (0 )]). T ,
184
187
unit = elements [0 ].unit ,
185
188
boundary_positions = None ,
186
189
)
@@ -202,11 +205,14 @@ def plot(self, *args, backend="matplotlib", **kwargs):
202
205
kwargs ["title" ] = kwargs .get ("title" , "\n " .join (wrap (self .name , wrapwidth )))
203
206
layercolor = kwargs .pop ("layercolor" , "gray" )
204
207
208
+ ymax = max (0 , self ._values .max () if self ._values .shape [1 ] == 1 else self ._values [:, 0 ].max () + self ._values [:, 1 ].max ())
205
209
if backend == "matplotlib" :
210
+ if self ._values .shape [1 ] == 2 :
211
+ kwargs ["yerr" ] = kwargs .get ("yerr" , "std" )
206
212
kwargs ["xlabel" ] = kwargs .get ("xlabel" , "Cortical depth" )
207
213
kwargs ["ylabel" ] = kwargs .get ("ylabel" , self .unit )
208
214
kwargs ["grid" ] = kwargs .get ("grid" , True )
209
- kwargs ["ylim" ] = kwargs .get ("ylim" , ( 0 , max ( self . _values )))
215
+ kwargs ["ylim" ] = kwargs .get ("ylim" , ymax ),
210
216
axs = self .data .plot (* args , ** kwargs , backend = backend )
211
217
212
218
if self .boundaries_mapped :
@@ -225,6 +231,8 @@ def plot(self, *args, backend="matplotlib", **kwargs):
225
231
axs .set_title (axs .get_title (), fontsize = "medium" )
226
232
return axs
227
233
elif backend == "plotly" :
234
+ if self ._values .shape [1 ] == 2 :
235
+ kwargs ["error_y" ] = kwargs .get ("error_y" , "std" )
228
236
kwargs ["title" ] = kwargs ["title" ].replace ("\n " , "<br>" )
229
237
kwargs ["labels" ] = {
230
238
"index" : kwargs .pop ("xlabel" , None ) or kwargs .pop ("index" , "Cortical depth" ),
@@ -241,7 +249,7 @@ def plot(self, *args, backend="matplotlib", **kwargs):
241
249
)
242
250
fig .update_layout (
243
251
showlegend = False ,
244
- yaxis_range = (0 , max ( self . _values ) ),
252
+ yaxis_range = (0 , ymax ),
245
253
title = dict (
246
254
automargin = True , yref = "container" , xref = "container" ,
247
255
pad = dict (t = 40 ), xanchor = "left" , yanchor = "top"
0 commit comments