{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Viewlims\n\nCreates two identical panels.  Zooming in on the right panel will show\na rectangle in the first panel, denoting the zoomed region.\n\n<div class=\"alert alert-info\"><h4>Note</h4><p>This example exercises the interactive capabilities of Matplotlib, and this\n    will not appear in the static documentation. Please run this code on your\n    machine to see the interactivity.\n\n    You can copy and paste individual parts, or download the entire example\n    using the link at the bottom of the page.</p></div>\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import functools\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrom matplotlib.patches import Rectangle\n\n\n# A class that will regenerate a fractal set as we zoom in, so that you\n# can actually see the increasing detail.  A box in the left panel will show\n# the area to which we are zoomed.\nclass MandelbrotDisplay:\n    def __init__(self, h=500, w=500, niter=50, radius=2., power=2):\n        self.height = h\n        self.width = w\n        self.niter = niter\n        self.radius = radius\n        self.power = power\n\n    def compute_image(self, xlim, ylim):\n        self.x = np.linspace(*xlim, self.width)\n        self.y = np.linspace(*ylim, self.height).reshape(-1, 1)\n        c = self.x + 1.0j * self.y\n        threshold_time = np.zeros((self.height, self.width))\n        z = np.zeros(threshold_time.shape, dtype=complex)\n        mask = np.ones(threshold_time.shape, dtype=bool)\n        for i in range(self.niter):\n            z[mask] = z[mask]**self.power + c[mask]\n            mask = (np.abs(z) < self.radius)\n            threshold_time += mask\n        return threshold_time\n\n    def ax_update(self, ax):\n        ax.set_autoscale_on(False)  # Otherwise, infinite loop\n        # Get the number of points from the number of pixels in the window\n        self.width, self.height = ax.patch.get_window_extent().size.round().astype(int)\n        # Update the image object with our new data and extent\n        ax.images[-1].set(data=self.compute_image(ax.get_xlim(), ax.get_ylim()),\n                          extent=(*ax.get_xlim(), *ax.get_ylim()))\n        ax.figure.canvas.draw_idle()\n\n\nmd = MandelbrotDisplay()\n\nfig1, (ax_full, ax_zoom) = plt.subplots(1, 2)\nax_zoom.imshow([[0]], origin=\"lower\")  # Empty initial image.\nax_zoom.set_title(\"Zoom here\")\n\nrect = Rectangle(\n    [0, 0], 0, 0, facecolor=\"none\", edgecolor=\"black\", linewidth=1.0)\nax_full.add_patch(rect)\n\n\ndef update_rect(rect, ax):  # Let the rectangle track the bounds of the zoom axes.\n    xlo, xhi = ax.get_xlim()\n    ylo, yhi = ax.get_ylim()\n    rect.set_bounds((xlo, ylo, xhi - xlo, yhi - ylo))\n    ax.figure.canvas.draw_idle()\n\n\n# Connect for changing the view limits.\nax_zoom.callbacks.connect(\"xlim_changed\", functools.partial(update_rect, rect))\nax_zoom.callbacks.connect(\"ylim_changed\", functools.partial(update_rect, rect))\n\nax_zoom.callbacks.connect(\"xlim_changed\", md.ax_update)\nax_zoom.callbacks.connect(\"ylim_changed\", md.ax_update)\n\n# Initialize: trigger image computation by setting view limits; set colormap limits;\n# copy image to full view.\nax_zoom.set(xlim=(-2, .5), ylim=(-1.25, 1.25))\nim = ax_zoom.images[0]\nax_zoom.images[0].set(clim=(im.get_array().min(), im.get_array().max()))\nax_full.imshow(im.get_array(), extent=im.get_extent(), origin=\"lower\")\n\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.14.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}