Coverage for /usr/local/lib/python3.11/dist-packages/grond/plot/config.py: 54%

104 statements  

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

1from pyrocko.guts import Object, Float, Int, List, Tuple, String, load, clone 

2 

3from grond.meta import GrondError 

4 

5guts_prefix = 'grond' 

6 

7 

8inch = 2.54 

9points = inch / 72.0 

10 

11 

12class PlotFormat(Object): 

13 

14 @property 

15 def extension(self): 

16 return self.name 

17 

18 def get_dpi(self, size_cm): 

19 return None 

20 

21 def render_mpl(self, fig, path, **kwargs): 

22 raise NotImplementedError 

23 

24 def render_automap(self, automap, path, **kwargs): 

25 raise NotImplementedError 

26 

27 

28class PNG(PlotFormat): 

29 name = 'png' 

30 

31 dpi = Int.T( 

32 optional=True, 

33 help='DPI of the figure') 

34 size_pixels = Int.T( 

35 optional=True, 

36 help='Size in pixels') 

37 width_pixels = Int.T( 

38 optional=True, 

39 help='Width in pixels') 

40 height_pixels = Int.T( 

41 optional=True, 

42 help='Height in pixels') 

43 

44 @property 

45 def extension(self): 

46 if self.dpi is not None: 

47 return 'd%i.png' % self.dpi 

48 elif self.size_pixels is not None: 

49 return 's%i.png' % self.size_pixels 

50 elif self.width_pixels is not None: 

51 return 'w%i.png' % self.width_pixels 

52 elif self.height_pixels is not None: 

53 return 'h%i.png' % self.height_pixels 

54 else: 

55 return 'd100.png' 

56 

57 def get_dpi(self, size_cm): 

58 w_cm, h_cm = size_cm 

59 w_inch, h_inch = w_cm/inch, h_cm/inch 

60 if self.dpi: 

61 return self.dpi 

62 elif self.size_pixels is not None: 

63 return min(self.size_pixels/w_inch, self.size_pixels/h_inch) 

64 elif self.width_pixels is not None: 

65 return self.width_pixels/w_inch 

66 elif self.height_pixels is not None: 

67 return self.height_pixels/h_inch 

68 else: 

69 return 100.0 

70 

71 def render_mpl(self, fig, path, **kwargs): 

72 return fig.savefig(path, format=self.name, **kwargs) 

73 

74 def render_automap(self, automap, path, **kwargs): 

75 return automap.save(path, **kwargs) 

76 

77 

78class PDF(PlotFormat): 

79 name = 'pdf' 

80 

81 dpi = Int.T( 

82 default=150, 

83 help='DPI of the figure') 

84 

85 def get_dpi(self, size_cm): 

86 return self.dpi 

87 

88 def render_mpl(self, fig, path, **kwargs): 

89 return fig.savefig(path, format=self.name, **kwargs) 

90 

91 def render_automap(self, automap, path, **kwargs): 

92 return automap.save(path, **kwargs) 

93 

94 

95class SVG(PlotFormat): 

96 name = 'svg' 

97 

98 dpi = Int.T( 

99 default=150, 

100 help='DPI of the figure') 

101 

102 def get_dpi(self, size_cm): 

103 return self.dpi 

104 

105 def render_mpl(self, fig, path, **kwargs): 

106 return fig.savefig(path, format=self.name, **kwargs) 

107 

108 def render_automap(self, automap, path, **kwargs): 

109 return automap.save(path, **kwargs) 

110 

111 

112class HTML(PlotFormat): 

113 name = 'html' 

114 

115 @property 

116 def extension(self): 

117 return 'html' 

118 

119 def render_mpl(self, fig, path, **kwargs): 

120 import mpld3 

121 kwargs.pop('dpi') 

122 

123 mpld3.save_html( 

124 fig, 

125 fileobj=path, 

126 **kwargs) 

127 

128 

129class PlotConfig(Object): 

130 name = 'undefined' 

131 variant = String.T( 

132 default='default', 

133 help='Variant of the plot (if applicable)') 

134 formats = List.T( 

135 PlotFormat.T(), 

136 default=[PNG()], 

137 help='Format of the plot') 

138 size_cm = Tuple.T( 

139 2, Float.T(), 

140 help='size of the plot') 

141 font_size = Float.T( 

142 default=10., 

143 help='font size') 

144 

145 @property 

146 def size_inch(self): 

147 return self.size_cm[0]/inch, self.size_cm[1]/inch 

148 

149 @property 

150 def size_points(self): 

151 return self.size_cm[0]/points, self.size_cm[1]/points 

152 

153 def make(self, environ): 

154 pass 

155 

156 

157class PlotConfigCollection(Object): 

158 plot_configs = List.T(PlotConfig.T()) 

159 

160 @classmethod 

161 def load(cls, path): 

162 from grond.plot import get_all_plot_classes 

163 get_all_plot_classes() # make sure all plot classes are loaded 

164 collection = load(filename=path) 

165 if not isinstance(collection, PlotConfigCollection): 

166 raise GrondError( 

167 'invalid plot collection configuration in file "%s"' % path) 

168 

169 return collection 

170 

171 def get_weeded(self, env): 

172 '''Get subset of plot configs supported by the current environment.''' 

173 

174 plot_classes = env.get_plot_classes() 

175 plot_configs_avail = [ 

176 clone(pc) 

177 for pc in self.plot_configs 

178 if pc.__class__ in plot_classes] 

179 

180 return PlotConfigCollection(plot_configs=plot_configs_avail) 

181 

182 

183__all__ = [ 

184 'PlotFormat', 

185 'PNG', 

186 'PDF', 

187 'PlotConfig', 

188 'PlotConfigCollection', 

189]