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-10-28 13:13 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-28 13:13 +0000
1from pyrocko.guts import Object, Float, Int, List, Tuple, String, load, clone
3from grond.meta import GrondError
5guts_prefix = 'grond'
8inch = 2.54
9points = inch / 72.0
12class PlotFormat(Object):
14 @property
15 def extension(self):
16 return self.name
18 def get_dpi(self, size_cm):
19 return None
21 def render_mpl(self, fig, path, **kwargs):
22 raise NotImplementedError
24 def render_automap(self, automap, path, **kwargs):
25 raise NotImplementedError
28class PNG(PlotFormat):
29 name = 'png'
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')
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'
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
71 def render_mpl(self, fig, path, **kwargs):
72 return fig.savefig(path, format=self.name, **kwargs)
74 def render_automap(self, automap, path, **kwargs):
75 return automap.save(path, **kwargs)
78class PDF(PlotFormat):
79 name = 'pdf'
81 dpi = Int.T(
82 default=150,
83 help='DPI of the figure')
85 def get_dpi(self, size_cm):
86 return self.dpi
88 def render_mpl(self, fig, path, **kwargs):
89 return fig.savefig(path, format=self.name, **kwargs)
91 def render_automap(self, automap, path, **kwargs):
92 return automap.save(path, **kwargs)
95class SVG(PlotFormat):
96 name = 'svg'
98 dpi = Int.T(
99 default=150,
100 help='DPI of the figure')
102 def get_dpi(self, size_cm):
103 return self.dpi
105 def render_mpl(self, fig, path, **kwargs):
106 return fig.savefig(path, format=self.name, **kwargs)
108 def render_automap(self, automap, path, **kwargs):
109 return automap.save(path, **kwargs)
112class HTML(PlotFormat):
113 name = 'html'
115 @property
116 def extension(self):
117 return 'html'
119 def render_mpl(self, fig, path, **kwargs):
120 import mpld3
121 kwargs.pop('dpi')
123 mpld3.save_html(
124 fig,
125 fileobj=path,
126 **kwargs)
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')
145 @property
146 def size_inch(self):
147 return self.size_cm[0]/inch, self.size_cm[1]/inch
149 @property
150 def size_points(self):
151 return self.size_cm[0]/points, self.size_cm[1]/points
153 def make(self, environ):
154 pass
157class PlotConfigCollection(Object):
158 plot_configs = List.T(PlotConfig.T())
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)
169 return collection
171 def get_weeded(self, env):
172 '''Get subset of plot configs supported by the current environment.'''
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]
180 return PlotConfigCollection(plot_configs=plot_configs_avail)
183__all__ = [
184 'PlotFormat',
185 'PNG',
186 'PDF',
187 'PlotConfig',
188 'PlotConfigCollection',
189]