|
25 | 25 | from PIL import Image |
26 | 26 |
|
27 | 27 | import compas |
| 28 | +from compas.geometry import allclose |
28 | 29 | from .artists import PlotterArtist |
29 | 30 |
|
30 | 31 |
|
@@ -213,31 +214,53 @@ def pause(self, pause: float) -> None: |
213 | 214 | plt.pause(pause) |
214 | 215 |
|
215 | 216 | def zoom_extents(self, padding: Optional[int] = None) -> None: |
216 | | - """Zoom the view to the bounding box of all objects.""" |
217 | | - padding = padding or 0 |
| 217 | + """Zoom the view to the bounding box of all objects. |
| 218 | +
|
| 219 | + Parameters |
| 220 | + ---------- |
| 221 | + padding : int, optional |
| 222 | + Extra padding around the bounding box of all objects. |
| 223 | + """ |
| 224 | + padding = padding or 0.0 |
218 | 225 | width, height = self.figsize |
219 | 226 | fig_aspect = width / height |
| 227 | + |
220 | 228 | data = [] |
221 | 229 | for artist in self.artists: |
222 | 230 | data += artist.data |
223 | | - x, y = zip(* data) |
| 231 | + |
| 232 | + x, y = zip(*data) |
| 233 | + |
224 | 234 | xmin = min(x) |
225 | 235 | xmax = max(x) |
226 | 236 | ymin = min(y) |
227 | 237 | ymax = max(y) |
228 | | - xspan = xmax - xmin + padding |
229 | | - yspan = ymax - ymin + padding |
| 238 | + xdiff = xmax - xmin |
| 239 | + ydiff = ymax - ymin |
| 240 | + |
| 241 | + xmin = xmin - 0.1 * xdiff - padding |
| 242 | + xmax = xmax + 0.1 * xdiff + padding |
| 243 | + ymin = ymin - 0.1 * ydiff - padding |
| 244 | + ymax = ymax + 0.1 * ydiff + padding |
| 245 | + |
| 246 | + xspan = xmax - xmin |
| 247 | + yspan = ymax - ymin |
230 | 248 | data_aspect = xspan / yspan |
231 | | - xlim = [xmin - 0.1 * xspan, xmax + 0.1 * xspan] |
232 | | - ylim = [ymin - 0.1 * yspan, ymax + 0.1 * yspan] |
| 249 | + |
233 | 250 | if data_aspect < fig_aspect: |
234 | 251 | scale = fig_aspect / data_aspect |
235 | | - xlim[0] *= scale |
236 | | - xlim[1] *= scale |
| 252 | + xpad = (xspan * (scale - 1.0)) / 2.0 |
| 253 | + xmin -= xpad |
| 254 | + xmax += xpad |
237 | 255 | else: |
238 | 256 | scale = data_aspect / fig_aspect |
239 | | - ylim[0] *= scale |
240 | | - ylim[1] *= scale |
| 257 | + ypad = (yspan * (scale - 1.0)) / 2.0 |
| 258 | + ymin -= ypad |
| 259 | + ymax += ypad |
| 260 | + assert allclose([fig_aspect], [(xmax - xmin) / (ymax - ymin)]) |
| 261 | + |
| 262 | + xlim = [xmin, xmax] |
| 263 | + ylim = [ymin, ymax] |
241 | 264 | self.viewbox = (xlim, ylim) |
242 | 265 | self.axes.set_xlim(*xlim) |
243 | 266 | self.axes.set_ylim(*ylim) |
|
0 commit comments