widgets.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. """
  2. ========================
  3. Widget testing utilities
  4. ========================
  5. See also :mod:`matplotlib.tests.test_widgets`.
  6. """
  7. from unittest import mock
  8. import matplotlib.pyplot as plt
  9. def get_ax():
  10. """Create a plot and return its axes."""
  11. fig, ax = plt.subplots(1, 1)
  12. ax.plot([0, 200], [0, 200])
  13. ax.set_aspect(1.0)
  14. ax.figure.canvas.draw()
  15. return ax
  16. def noop(*args, **kwargs):
  17. pass
  18. def mock_event(ax, button=1, xdata=0, ydata=0, key=None, step=1):
  19. r"""
  20. Create a mock event that can stand in for `.Event` and its subclasses.
  21. This event is intended to be used in tests where it can be passed into
  22. event handling functions.
  23. Parameters
  24. ----------
  25. ax : `~matplotlib.axes.Axes`
  26. The axes the event will be in.
  27. xdata : float
  28. x coord of mouse in data coords.
  29. ydata : float
  30. y coord of mouse in data coords.
  31. button : None or `MouseButton` or {'up', 'down'}
  32. The mouse button pressed in this event (see also `.MouseEvent`).
  33. key : None or str
  34. The key pressed when the mouse event triggered (see also `.KeyEvent`).
  35. step : int
  36. Number of scroll steps (positive for 'up', negative for 'down').
  37. Returns
  38. -------
  39. event
  40. A `.Event`\-like Mock instance.
  41. """
  42. event = mock.Mock()
  43. event.button = button
  44. event.x, event.y = ax.transData.transform([(xdata, ydata),
  45. (xdata, ydata)])[0]
  46. event.xdata, event.ydata = xdata, ydata
  47. event.inaxes = ax
  48. event.canvas = ax.figure.canvas
  49. event.key = key
  50. event.step = step
  51. event.guiEvent = None
  52. event.name = 'Custom'
  53. return event
  54. def do_event(tool, etype, button=1, xdata=0, ydata=0, key=None, step=1):
  55. """
  56. Trigger an event on the given tool.
  57. Parameters
  58. ----------
  59. tool : matplotlib.widgets.AxesWidget
  60. etype : str
  61. The event to trigger.
  62. xdata : float
  63. x coord of mouse in data coords.
  64. ydata : float
  65. y coord of mouse in data coords.
  66. button : None or `MouseButton` or {'up', 'down'}
  67. The mouse button pressed in this event (see also `.MouseEvent`).
  68. key : None or str
  69. The key pressed when the mouse event triggered (see also `.KeyEvent`).
  70. step : int
  71. Number of scroll steps (positive for 'up', negative for 'down').
  72. """
  73. event = mock_event(tool.ax, button, xdata, ydata, key, step)
  74. func = getattr(tool, etype)
  75. func(event)
  76. def click_and_drag(tool, start, end, key=None):
  77. """
  78. Helper to simulate a mouse drag operation.
  79. Parameters
  80. ----------
  81. tool : `~matplotlib.widgets.Widget`
  82. start : [float, float]
  83. Starting point in data coordinates.
  84. end : [float, float]
  85. End point in data coordinates.
  86. key : None or str
  87. An optional key that is pressed during the whole operation
  88. (see also `.KeyEvent`).
  89. """
  90. if key is not None:
  91. # Press key
  92. do_event(tool, 'on_key_press', xdata=start[0], ydata=start[1],
  93. button=1, key=key)
  94. # Click, move, and release mouse
  95. do_event(tool, 'press', xdata=start[0], ydata=start[1], button=1)
  96. do_event(tool, 'onmove', xdata=end[0], ydata=end[1], button=1)
  97. do_event(tool, 'release', xdata=end[0], ydata=end[1], button=1)
  98. if key is not None:
  99. # Release key
  100. do_event(tool, 'on_key_release', xdata=end[0], ydata=end[1],
  101. button=1, key=key)