Coverage for nilearn/_utils/plotting.py: 0%

69 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-16 12:32 +0200

1import numpy as np 

2import pandas as pd 

3from matplotlib import pyplot as plt 

4 

5from nilearn.externals import tempita 

6from nilearn.plotting import ( 

7 plot_contrast_matrix, 

8 plot_design_matrix, 

9 plot_design_matrix_correlation, 

10) 

11from nilearn.reporting.utils import ( 

12 figure_to_png_base64, 

13) 

14 

15 

16def generate_design_matrices_figures( 

17 design_matrices, design_matrices_dict=None, output=None 

18): 

19 """Generate plot for design matrices and their correlation matrices. 

20 

21 After generating the figure it can either : 

22 

23 - convert it to bytes for insertion into HTML report 

24 - save it to disk if the appropriate "output" was passed 

25 

26 design_matrices_dict is a dict-like (tempita.bunc) 

27 that contains the figure (as bytes or relative path). 

28 A tempita bunch is used to facilitate injecting its content 

29 into HTML templates. 

30 If a design_matrices_dict is passed its content will be updated. 

31 

32 Returns 

33 ------- 

34 design_matrices_dict : tempita.bunch 

35 

36 design_matrices_dict[i_run].design_matrix 

37 design_matrices_dict[i_run].correlation_matrix 

38 

39 """ 

40 if design_matrices_dict is None: 

41 design_matrices_dict = tempita.bunch() 

42 

43 if design_matrices is None: 

44 return design_matrices_dict 

45 

46 for i_run, design_matrix in enumerate(design_matrices): 

47 dmtx_plot = plot_design_matrix(design_matrix) 

48 dmtx_plot = resize_plot_inches(dmtx_plot, height_change=0.3) 

49 dmtx_fig = None 

50 if output: 

51 # the try is mostly here in case badly formed dict 

52 try: 

53 dmtx_fig = output["design_matrices_dict"][i_run][ 

54 "design_matrix_png" 

55 ] 

56 dmtx_plot.figure.savefig(output["dir"] / dmtx_fig) 

57 except Exception: # pragma: no cover 

58 dmtx_fig = None 

59 if dmtx_fig is None: 

60 dmtx_fig = figure_to_png_base64(dmtx_plot) 

61 # prevents sphinx-gallery & jupyter 

62 # from scraping & inserting plots 

63 plt.close("all") 

64 

65 dmtx_cor_fig = None 

66 # in case of second level model with a single regressor 

67 # (for example one-sample t-test) 

68 # no point in plotting the correlation 

69 if ( 

70 isinstance(design_matrix, np.ndarray) 

71 and design_matrix.shape[1] > 1 

72 ) or ( 

73 isinstance(design_matrix, pd.DataFrame) 

74 and len(design_matrix.columns) > 1 

75 ): 

76 dmtx_cor_plot = plot_design_matrix_correlation( 

77 design_matrix, tri="diag" 

78 ) 

79 dmtx_cor_plot = resize_plot_inches( 

80 dmtx_cor_plot, height_change=0.3 

81 ) 

82 if output: 

83 try: 

84 dmtx_cor_fig = output["design_matrices_dict"][i_run][ 

85 "correlation_matrix_png" 

86 ] 

87 dmtx_cor_plot.figure.savefig(output["dir"] / dmtx_cor_fig) 

88 except KeyError: # pragma: no cover 

89 dmtx_cor_fig = None 

90 if dmtx_cor_fig is None: 

91 dmtx_cor_fig = figure_to_png_base64(dmtx_cor_plot) 

92 # prevents sphinx-gallery & jupyter 

93 # from scraping & inserting plots 

94 plt.close("all") 

95 

96 if i_run not in design_matrices_dict: 

97 design_matrices_dict[i_run] = tempita.bunch( 

98 design_matrix=None, correlation_matrix=None 

99 ) 

100 

101 design_matrices_dict[i_run]["design_matrix_png"] = dmtx_fig 

102 design_matrices_dict[i_run]["correlation_matrix_png"] = dmtx_cor_fig 

103 

104 return design_matrices_dict 

105 

106 

107def generate_contrast_matrices_figures( 

108 design_matrices, contrasts=None, contrasts_dict=None, output=None 

109): 

110 """Generate plot for contrasts matrices. 

111 

112 After generating the figure it can either : 

113 

114 - convert it to bytes for insertion into HTML report 

115 - save it to disk if the appropriate "output" was passed 

116 

117 contrasts_dict is a dict-like (tempita.bunc) 

118 that contains the figure (as bytes or relative path). 

119 A tempita bunch is used to facilitate injecting its content 

120 into HTML templates. 

121 If a contrasts_dict is passed its content will be updated. 

122 

123 Returns 

124 ------- 

125 contrasts_dict : tempita.bunch 

126 

127 contrasts_dict[contrast_name] 

128 

129 

130 """ 

131 if contrasts_dict is None: 

132 contrasts_dict = tempita.bunch() 

133 

134 if design_matrices is None or not contrasts: 

135 return contrasts_dict 

136 

137 for i_run, design_matrix in enumerate(design_matrices): 

138 tmp = {} 

139 for contrast_name, contrast_data in contrasts.items(): 

140 contrast_plot = plot_contrast_matrix( 

141 contrast_data, design_matrix, colorbar=True 

142 ) 

143 

144 contrast_plot.set_xlabel(contrast_name) 

145 

146 contrast_plot.figure.set_figheight(2) 

147 

148 contrast_fig = None 

149 if output: 

150 try: 

151 contrast_fig = output["contrasts_dict"][i_run][ 

152 contrast_name 

153 ] 

154 contrast_plot.figure.savefig(output["dir"] / contrast_fig) 

155 except KeyError: # pragma: no cover 

156 contrast_fig = None 

157 if contrast_fig is None: 

158 contrast_fig = figure_to_png_base64(contrast_plot) 

159 # prevents sphinx-gallery & jupyter 

160 # from scraping & inserting plots 

161 plt.close("all") 

162 

163 tmp[contrast_name] = contrast_fig 

164 

165 contrasts_dict[i_run] = tempita.bunch(**tmp) 

166 

167 return contrasts_dict 

168 

169 

170def resize_plot_inches(plot, width_change=0, height_change=0): 

171 """Accept a matplotlib figure or axes object and resize it (in inches). 

172 

173 Returns the original object. 

174 

175 Parameters 

176 ---------- 

177 plot : matplotlib.Figure() or matplotlib.Axes() 

178 The matplotlib Figure/Axes object to be resized. 

179 

180 width_change : float, default=0 

181 The amount of change to be added on to original width. 

182 Use negative values for reducing figure dimensions. 

183 

184 height_change : float, default=0 

185 The amount of change to be added on to original height. 

186 Use negative values for reducing figure dimensions. 

187 

188 Returns 

189 ------- 

190 plot : matplotlib.Figure() or matplotlib.Axes() 

191 The matplotlib Figure/Axes object after being resized. 

192 

193 """ 

194 if not isinstance(plot, (plt.Figure)): 

195 orig_size = plot.figure.get_size_inches() 

196 else: 

197 orig_size = plot.get_size_inches() 

198 

199 new_size = ( 

200 orig_size[0] + width_change, 

201 orig_size[1] + height_change, 

202 ) 

203 

204 if not isinstance(plot, (plt.Figure)): 

205 plot.figure.set_size_inches(new_size, forward=True) 

206 else: 

207 plot.set_size_inches(new_size, forward=True) 

208 

209 return plot