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