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 2024-11-27 15:15 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-11-27 15:15 +0000
1# https://pyrocko.org/grond - GPLv3
2#
3# The Grond Developers, 21st Century
4from pyrocko.guts import Object, Float, Int, List, Tuple, String, load, clone
6from grond.meta import GrondError
8guts_prefix = 'grond'
11inch = 2.54
12points = inch / 72.0
15class PlotFormat(Object):
17 @property
18 def extension(self):
19 return self.name
21 def get_dpi(self, size_cm):
22 return None
24 def render_mpl(self, fig, path, **kwargs):
25 raise NotImplementedError
27 def render_automap(self, automap, path, **kwargs):
28 raise NotImplementedError
31class PNG(PlotFormat):
32 name = 'png'
34 dpi = Int.T(
35 optional=True,
36 help='DPI of the figure')
37 size_pixels = Int.T(
38 optional=True,
39 help='Size in pixels')
40 width_pixels = Int.T(
41 optional=True,
42 help='Width in pixels')
43 height_pixels = Int.T(
44 optional=True,
45 help='Height in pixels')
47 @property
48 def extension(self):
49 if self.dpi is not None:
50 return 'd%i.png' % self.dpi
51 elif self.size_pixels is not None:
52 return 's%i.png' % self.size_pixels
53 elif self.width_pixels is not None:
54 return 'w%i.png' % self.width_pixels
55 elif self.height_pixels is not None:
56 return 'h%i.png' % self.height_pixels
57 else:
58 return 'd100.png'
60 def get_dpi(self, size_cm):
61 w_cm, h_cm = size_cm
62 w_inch, h_inch = w_cm/inch, h_cm/inch
63 if self.dpi:
64 return self.dpi
65 elif self.size_pixels is not None:
66 return min(self.size_pixels/w_inch, self.size_pixels/h_inch)
67 elif self.width_pixels is not None:
68 return self.width_pixels/w_inch
69 elif self.height_pixels is not None:
70 return self.height_pixels/h_inch
71 else:
72 return 100.0
74 def render_mpl(self, fig, path, **kwargs):
75 return fig.savefig(path, format=self.name, **kwargs)
77 def render_automap(self, automap, path, **kwargs):
78 return automap.save(path, **kwargs)
81class PDF(PlotFormat):
82 name = 'pdf'
84 dpi = Int.T(
85 default=150,
86 help='DPI of the figure')
88 def get_dpi(self, size_cm):
89 return self.dpi
91 def render_mpl(self, fig, path, **kwargs):
92 return fig.savefig(path, format=self.name, **kwargs)
94 def render_automap(self, automap, path, **kwargs):
95 return automap.save(path, **kwargs)
98class SVG(PlotFormat):
99 name = 'svg'
101 dpi = Int.T(
102 default=150,
103 help='DPI of the figure')
105 def get_dpi(self, size_cm):
106 return self.dpi
108 def render_mpl(self, fig, path, **kwargs):
109 return fig.savefig(path, format=self.name, **kwargs)
111 def render_automap(self, automap, path, **kwargs):
112 return automap.save(path, **kwargs)
115class HTML(PlotFormat):
116 name = 'html'
118 @property
119 def extension(self):
120 return 'html'
122 def render_mpl(self, fig, path, **kwargs):
123 import mpld3
124 kwargs.pop('dpi')
126 mpld3.save_html(
127 fig,
128 fileobj=path,
129 **kwargs)
132class PlotConfig(Object):
133 name = 'undefined'
134 variant = String.T(
135 default='default',
136 help='Variant of the plot (if applicable)')
137 formats = List.T(
138 PlotFormat.T(),
139 default=[PNG()],
140 help='Format of the plot')
141 size_cm = Tuple.T(
142 2, Float.T(),
143 help='size of the plot')
144 font_size = Float.T(
145 default=10.,
146 help='font size')
148 @property
149 def size_inch(self):
150 return self.size_cm[0]/inch, self.size_cm[1]/inch
152 @property
153 def size_points(self):
154 return self.size_cm[0]/points, self.size_cm[1]/points
156 def make(self, environ):
157 pass
160class PlotConfigCollection(Object):
161 plot_configs = List.T(PlotConfig.T())
163 @classmethod
164 def load(cls, path):
165 from grond.plot import get_all_plot_classes
166 get_all_plot_classes() # make sure all plot classes are loaded
167 collection = load(filename=path)
168 if not isinstance(collection, PlotConfigCollection):
169 raise GrondError(
170 'invalid plot collection configuration in file "%s"' % path)
172 return collection
174 def get_weeded(self, env):
175 '''Get subset of plot configs supported by the current environment.'''
177 plot_classes = env.get_plot_classes()
178 plot_configs_avail = [
179 clone(pc)
180 for pc in self.plot_configs
181 if pc.__class__ in plot_classes]
183 return PlotConfigCollection(plot_configs=plot_configs_avail)
186__all__ = [
187 'PlotFormat',
188 'PNG',
189 'PDF',
190 'PlotConfig',
191 'PlotConfigCollection',
192]