Coverage for /usr/local/lib/python3.11/dist-packages/grond/problems/double_dc/plot.py: 27%

62 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2024-06-12 11:12 +0000

1import math 

2import logging 

3 

4from matplotlib import pyplot as plt 

5 

6from pyrocko.guts import Float, Tuple 

7from pyrocko import gf 

8from pyrocko.plot import mpl_init, beachball, mpl_color 

9 

10from grond import stats 

11from grond.plot.collection import PlotItem 

12from grond.plot.config import PlotConfig 

13 

14logger = logging.getLogger('grond.problem.double_dc.plot') 

15 

16guts_prefix = 'grond' 

17 

18km = 1e3 

19 

20 

21class DoubleDCDecompositionPlot(PlotConfig): 

22 ''' 

23 Double DC decomposition plot. 

24 ''' 

25 name = 'dc_decomposition' 

26 size_cm = Tuple.T(2, Float.T(), default=(15., 5.)) 

27 

28 def make(self, environ): 

29 cm = environ.get_plot_collection_manager() 

30 history = environ.get_history(subset='harvest') 

31 mpl_init(fontsize=self.font_size) 

32 cm.create_group_mpl( 

33 self, 

34 self.draw_figures(history), 

35 title=u'Double DC Decomposition', 

36 section='solution', 

37 feather_icon='sun', 

38 description=u''' 

39Double DC decomposition of the best and mean solution into its two contributing 

40focal mechanisms. 

41Shown are the ensemble best and the ensemble mean. The symbol size indicates 

42the relative strength of the mechanisms. The inversion result is consistent 

43and stable if ensemble mean and ensemble best have similar symbol size and 

44patterns. 

45''') 

46 

47 def draw_figures(self, history): 

48 fontsize = self.font_size 

49 

50 fig = plt.figure(figsize=self.size_inch) 

51 axes = fig.add_subplot(1, 1, 1, aspect=1.0) 

52 

53 fig.subplots_adjust(left=0., right=1., bottom=0., top=1.) 

54 

55 problem = history.problem 

56 models = history.models 

57 if models.size == 0: 

58 logger.warn('Empty models vector.') 

59 return [] 

60 

61 mean_source = stats.get_mean_source( 

62 problem, history.models) 

63 best_source = history.get_best_source() 

64 nlines_max = int(round(self.size_cm[1] / 5. * 4. - 1.0)) 

65 

66 def get_deco(source): 

67 if isinstance(source, gf.DoubleDCSource): 

68 return [source] + source.split() 

69 

70 lines = [] 

71 lines.append( 

72 ('Ensemble best', get_deco(best_source), mpl_color('aluminium5'))) 

73 lines.append( 

74 ('Ensemble mean', get_deco(mean_source), mpl_color('aluminium5'))) 

75 

76 mag_max = max(dc.magnitude for (_, line, _) in lines for dc in line) 

77 

78 for xpos, label in [ 

79 (0., 'Double DC'), 

80 (2., 'DC 1'), 

81 (4., 'DC 2')]: 

82 

83 axes.annotate( 

84 label, 

85 xy=(1 + xpos, nlines_max), 

86 xycoords='data', 

87 xytext=(0., 0.), 

88 textcoords='offset points', 

89 ha='center', 

90 va='center', 

91 color='black', 

92 fontsize=fontsize) 

93 

94 for i, (label, deco, color_t) in enumerate(lines): 

95 ypos = nlines_max - i - 1.0 

96 [ddc, dc1, dc2] = deco 

97 size0 = ddc.magnitude / mag_max 

98 

99 axes.annotate( 

100 label, 

101 xy=(-2., ypos), 

102 xycoords='data', 

103 xytext=(0., 0.), 

104 textcoords='offset points', 

105 ha='left', 

106 va='center', 

107 color='black', 

108 fontsize=fontsize) 

109 

110 for xpos, dc_part, ratio, ops in [ 

111 (0., ddc, 1., '='), 

112 (2., dc1, dc1.magnitude / mag_max, '+'), 

113 (4., dc2, dc2.magnitude / mag_max, None)]: 

114 

115 if ratio > 1e-4: 

116 try: 

117 beachball.plot_beachball_mpl( 

118 dc_part.pyrocko_moment_tensor(), axes, 

119 position=(1. + xpos, ypos), 

120 size=0.9 * size0 * math.sqrt(ratio), 

121 size_units='data', 

122 color_t=color_t, 

123 linewidth=1.0) 

124 except beachball.BeachballError as e: 

125 logger.warn(str(e)) 

126 axes.annotate( 

127 'ERROR', 

128 xy=(1. + xpos, ypos), 

129 ha='center', 

130 va='center', 

131 color='red', 

132 fontsize=fontsize) 

133 else: 

134 axes.annotate( 

135 'N/A', 

136 xy=(1. + xpos, ypos), 

137 ha='center', 

138 va='center', 

139 color='black', 

140 fontsize=fontsize) 

141 if ops is not None: 

142 axes.annotate( 

143 ops, 

144 xy=(2. + xpos, ypos), 

145 ha='center', 

146 va='center', 

147 color='black', 

148 fontsize=fontsize) 

149 axes.axison = False 

150 axes.set_xlim(-2.25, 9.75) 

151 axes.set_ylim(-0.5, nlines_max+0.5) 

152 item = PlotItem(name='main') 

153 return [[item, fig]]