交互式函数

交互式函数#

这个提供了交互式函数的使用示例,如 ginput、waitforbuttonpress 和手动 clabel 放置。

# %matplotlib tk
import time

import matplotlib.pyplot as plt
import numpy as np


def tellme(s):
    print(s)
    plt.title(s, fontsize=16)
    plt.draw()

通过点击三个点定义一个三角形

plt.figure()
plt.xlim(0, 1)
plt.ylim(0, 1)

tellme('You will define a triangle, click to begin')

plt.waitforbuttonpress()

while True:
    pts = []
    while len(pts) < 3:
        tellme('Select 3 corners with mouse')
        pts = np.asarray(plt.ginput(3, timeout=-1))
        if len(pts) < 3:
            tellme('Too few points, starting over')
            time.sleep(1)  # Wait a second

    ph = plt.fill(pts[:, 0], pts[:, 1], 'r', lw=2)

    tellme('Happy? Key click for yes, mouse click for no')

    if plt.waitforbuttonpress():
        break

    # Get rid of fill
    for p in ph:
        p.remove()
You will define a triangle, click to begin
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
Cell In[2], line 7
      3 plt.ylim(0, 1)
      5 tellme('You will define a triangle, click to begin')
----> 7 plt.waitforbuttonpress()
      9 while True:
     10     pts = []

File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/matplotlib/pyplot.py:2807, in waitforbuttonpress(timeout)
   2805 @_copy_docstring_and_deprecators(Figure.waitforbuttonpress)
   2806 def waitforbuttonpress(timeout: float = -1) -> None | bool:
-> 2807     return gcf().waitforbuttonpress(timeout=timeout)

File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/matplotlib/figure.py:3508, in Figure.waitforbuttonpress(self, timeout)
   3505     event = ev
   3506     self.canvas.stop_event_loop()
-> 3508 _blocking_input.blocking_input_loop(
   3509     self, ["button_press_event", "key_press_event"], timeout, handler)
   3511 return None if event is None else event.name == "key_press_event"

File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/matplotlib/_blocking_input.py:26, in blocking_input_loop(figure, event_names, timeout, handler)
     24 cids = [figure.canvas.mpl_connect(name, handler) for name in event_names]
     25 try:
---> 26     figure.canvas.start_event_loop(timeout)  # Start event loop.
     27 finally:  # Run even on exception like ctrl-c.
     28     # Disconnect the callbacks.
     29     for cid in cids:

File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/matplotlib/backend_bases.py:2392, in FigureCanvasBase.start_event_loop(self, timeout)
   2390 while self._looping and counter * timestep < timeout:
   2391     self.flush_events()
-> 2392     time.sleep(timestep)
   2393     counter += 1

KeyboardInterrupt: 
../../../_images/aeae90c3e28a19fdef6854618839580b2824ce5e4d389e405a517586331a6128.png

现在根据距离三角形角的距离进行等高线绘制——仅作示例:

# Define a nice function of distance from individual pts
def f(x, y, pts):
    z = np.zeros_like(x)
    for p in pts:
        z = z + 1/(np.sqrt((x - p[0])**2 + (y - p[1])**2))
    return 1/z


X, Y = np.meshgrid(np.linspace(-1, 1, 51), np.linspace(-1, 1, 51))
Z = f(X, Y, pts)

CS = plt.contour(X, Y, Z, 20)

tellme('Use mouse to select contour label locations, middle button to finish')
CL = plt.clabel(CS, manual=True)
Use mouse to select contour label locations, middle button to finish
Select label locations manually using first mouse button.
End manual selection with second mouse button.

现在进行缩放:

tellme('Now do a nested zoom, click to begin')
plt.waitforbuttonpress()

while True:
    tellme('Select two corners of zoom, middle mouse button to finish')
    pts = plt.ginput(2, timeout=-1)
    if len(pts) < 2:
        break
    (x0, y0), (x1, y1) = pts
    xmin, xmax = sorted([x0, x1])
    ymin, ymax = sorted([y0, y1])
    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)

tellme('All Done!')
plt.show()
Now do a nested zoom, click to begin
Select two corners of zoom, middle mouse button to finish
Select two corners of zoom, middle mouse button to finish
Select two corners of zoom, middle mouse button to finish
Select two corners of zoom, middle mouse button to finish
Select two corners of zoom, middle mouse button to finish
Select two corners of zoom, middle mouse button to finish
Select two corners of zoom, middle mouse button to finish
Select two corners of zoom, middle mouse button to finish
Select two corners of zoom, middle mouse button to finish
All Done!
/tmp/ipykernel_3892400/2952028225.py:12: UserWarning: Attempting to set identical low and high xlims makes transformation singular; automatically expanding.
  plt.xlim(xmin, xmax)
/tmp/ipykernel_3892400/2952028225.py:13: UserWarning: Attempting to set identical low and high ylims makes transformation singular; automatically expanding.
  plt.ylim(ymin, ymax)