{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Interactive functions\n\nThis provides examples of uses of interactive functions, such as ginput,\nwaitforbuttonpress and manual clabel placement.\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 time\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\ndef tellme(s):\n    print(s)\n    plt.title(s, fontsize=16)\n    plt.draw()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Define a triangle by clicking three points\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.figure()\nplt.xlim(0, 1)\nplt.ylim(0, 1)\n\ntellme('You will define a triangle, click to begin')\n\nplt.waitforbuttonpress()\n\nwhile True:\n    pts = []\n    while len(pts) < 3:\n        tellme('Select 3 corners with mouse')\n        pts = np.asarray(plt.ginput(3, timeout=-1))\n        if len(pts) < 3:\n            tellme('Too few points, starting over')\n            time.sleep(1)  # Wait a second\n\n    ph = plt.fill(pts[:, 0], pts[:, 1], 'r', lw=2)\n\n    tellme('Happy? Key click for yes, mouse click for no')\n\n    if plt.waitforbuttonpress():\n        break\n\n    # Get rid of fill\n    for p in ph:\n        p.remove()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now contour according to distance from triangle\ncorners - just an example\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Define a nice function of distance from individual pts\ndef f(x, y, pts):\n    z = np.zeros_like(x)\n    for p in pts:\n        z = z + 1/(np.sqrt((x - p[0])**2 + (y - p[1])**2))\n    return 1/z\n\n\nX, Y = np.meshgrid(np.linspace(-1, 1, 51), np.linspace(-1, 1, 51))\nZ = f(X, Y, pts)\n\nCS = plt.contour(X, Y, Z, 20)\n\ntellme('Use mouse to select contour label locations, middle button to finish')\nCL = plt.clabel(CS, manual=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now do a zoom\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "tellme('Now do a nested zoom, click to begin')\nplt.waitforbuttonpress()\n\nwhile True:\n    tellme('Select two corners of zoom, middle mouse button to finish')\n    pts = plt.ginput(2, timeout=-1)\n    if len(pts) < 2:\n        break\n    (x0, y0), (x1, y1) = pts\n    xmin, xmax = sorted([x0, x1])\n    ymin, ymax = sorted([y0, y1])\n    plt.xlim(xmin, xmax)\n    plt.ylim(ymin, ymax)\n\ntellme('All Done!')\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
}