1515 view_img ,
1616)
1717from ridgeplot import ridgeplot
18+ from scipy import stats
1819from scipy .cluster .hierarchy import leaves_list , linkage , optimal_leaf_ordering
1920
20- from nimare .utils import _boolean_unmask
21-
2221TABLE_STYLE = [
2322 dict (
2423 selector = "th, td" ,
@@ -402,6 +401,60 @@ def plot_clusters(img, out_filename):
402401 fig .close ()
403402
404403
404+ def _plot_true_voxels (maps_arr , ids_ , out_filename ):
405+ """Plot percentage of valid voxels.
406+
407+ .. versionadded:: 0.2.2
408+
409+ """
410+ n_studies , n_voxels = maps_arr .shape
411+ mask = ~ np .isnan (maps_arr ) & (maps_arr != 0 )
412+
413+ x_label , y_label = "Voxels Included" , "ID"
414+ perc_voxs = mask .sum (axis = 1 ) / n_voxels
415+ valid_df = pd .DataFrame ({y_label : ids_ , x_label : perc_voxs })
416+ valid_sorted_df = valid_df .sort_values (x_label , ascending = True )
417+
418+ fig = px .bar (
419+ valid_sorted_df ,
420+ x = x_label ,
421+ y = y_label ,
422+ orientation = "h" ,
423+ color = x_label ,
424+ color_continuous_scale = "blues" ,
425+ range_color = (0 , 1 ),
426+ )
427+
428+ fig .update_xaxes (
429+ showline = True ,
430+ linewidth = 2 ,
431+ linecolor = "black" ,
432+ visible = True ,
433+ showticklabels = False ,
434+ title = None ,
435+ )
436+ fig .update_yaxes (
437+ showline = True ,
438+ linewidth = 2 ,
439+ linecolor = "black" ,
440+ visible = True ,
441+ ticktext = valid_sorted_df [y_label ].str .slice (0 , MAX_CHARS ).tolist (),
442+ )
443+
444+ height = n_studies * PXS_PER_STD
445+ fig .update_layout (
446+ height = height ,
447+ autosize = True ,
448+ font_size = 14 ,
449+ plot_bgcolor = "white" ,
450+ xaxis_gridcolor = "white" ,
451+ yaxis_gridcolor = "white" ,
452+ xaxis_gridwidth = 2 ,
453+ showlegend = False ,
454+ )
455+ fig .write_html (out_filename , full_html = True , include_plotlyjs = True )
456+
457+
405458def _plot_ridgeplot (maps_arr , ids_ , x_label , out_filename ):
406459 """Plot histograms of the images.
407460
@@ -446,7 +499,88 @@ def _plot_ridgeplot(maps_arr, ids_, x_label, out_filename):
446499 fig .write_html (out_filename , full_html = True , include_plotlyjs = True )
447500
448501
449- def _plot_relcov_map (maps_arr , masker , aggressive_mask , out_filename ):
502+ def _plot_sumstats (maps_arr , ids_ , out_filename ):
503+ """Plot summary statistics of the images.
504+
505+ .. versionadded:: 0.2.2
506+
507+ """
508+ n_studies = len (ids_ )
509+ mask = ~ np .isnan (maps_arr ) & (maps_arr != 0 )
510+ maps_lst = [maps_arr [i ][mask [i ]] for i in range (n_studies )]
511+
512+ stats_lbls = [
513+ "Mean" ,
514+ "STD" ,
515+ "Var" ,
516+ "Median" ,
517+ "Mode" ,
518+ "Min" ,
519+ "Max" ,
520+ "Skew" ,
521+ "Kurtosis" ,
522+ "Range" ,
523+ "Moment" ,
524+ "IQR" ,
525+ ]
526+ scores , id_lst = [], []
527+ for id_ , map_ in zip (ids_ , maps_lst ):
528+ scores .extend (
529+ [
530+ np .mean (map_ ),
531+ np .std (map_ ),
532+ np .var (map_ ),
533+ np .median (map_ ),
534+ stats .mode (map_ )[0 ],
535+ np .min (map_ ),
536+ np .max (map_ ),
537+ stats .skew (map_ ),
538+ stats .kurtosis (map_ ),
539+ np .max (map_ ) - np .min (map_ ),
540+ stats .moment (map_ , moment = 4 ),
541+ stats .iqr (map_ ),
542+ ]
543+ )
544+ id_lst .extend ([id_ ] * len (stats_lbls ))
545+
546+ stats_labels = stats_lbls * n_studies
547+ data_df = pd .DataFrame ({"ID" : id_lst , "Score" : scores , "Stat" : stats_labels })
548+
549+ fig = px .strip (
550+ data_df ,
551+ y = "Score" ,
552+ color = "ID" ,
553+ facet_col = "Stat" ,
554+ stripmode = "group" ,
555+ facet_col_wrap = 4 ,
556+ facet_col_spacing = 0.08 ,
557+ )
558+
559+ fig .update_xaxes (showline = True , linewidth = 2 , linecolor = "black" , mirror = True )
560+ fig .update_yaxes (
561+ constrain = "domain" ,
562+ matches = None ,
563+ showline = True ,
564+ linewidth = 2 ,
565+ linecolor = "black" ,
566+ mirror = True ,
567+ title = None ,
568+ )
569+ fig .update_layout (
570+ height = 900 ,
571+ autosize = True ,
572+ font_size = 14 ,
573+ plot_bgcolor = "white" ,
574+ xaxis_gridcolor = "white" ,
575+ yaxis_gridcolor = "white" ,
576+ xaxis_gridwidth = 2 ,
577+ showlegend = False ,
578+ )
579+ fig .for_each_yaxis (lambda yaxis : yaxis .update (showticklabels = True ))
580+ fig .write_html (out_filename , full_html = True , include_plotlyjs = True )
581+
582+
583+ def _plot_relcov_map (maps_arr , masker , out_filename ):
450584 """Plot relative coverage map.
451585
452586 .. versionadded:: 0.2.0
@@ -460,8 +594,6 @@ def _plot_relcov_map(maps_arr, masker, aggressive_mask, out_filename):
460594 binary_maps_arr = np .where ((- epsilon > maps_arr ) | (maps_arr > epsilon ), 1 , 0 )
461595 coverage_arr = np .sum (binary_maps_arr , axis = 0 ) / binary_maps_arr .shape [0 ]
462596
463- # Add bad voxels back to the arr to transform it back to an image
464- coverage_arr = _boolean_unmask (coverage_arr , aggressive_mask )
465597 coverage_img = masker .inverse_transform (coverage_arr )
466598
467599 # Plot coverage map
0 commit comments