backend_macosx.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import matplotlib as mpl
  2. from matplotlib import cbook
  3. from matplotlib._pylab_helpers import Gcf
  4. from matplotlib.backends import _macosx
  5. from matplotlib.backends.backend_agg import FigureCanvasAgg
  6. from matplotlib.backend_bases import (
  7. _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
  8. TimerBase)
  9. from matplotlib.figure import Figure
  10. from matplotlib.widgets import SubplotTool
  11. ########################################################################
  12. #
  13. # The following functions and classes are for pylab and implement
  14. # window/figure managers, etc...
  15. #
  16. ########################################################################
  17. class TimerMac(_macosx.Timer, TimerBase):
  18. """Subclass of `.TimerBase` using CFRunLoop timer events."""
  19. # completely implemented at the C-level (in _macosx.Timer)
  20. class FigureCanvasMac(_macosx.FigureCanvas, FigureCanvasAgg):
  21. """
  22. The canvas the figure renders into. Calls the draw and print fig
  23. methods, creates the renderers, etc...
  24. Events such as button presses, mouse movements, and key presses
  25. are handled in the C code and the base class methods
  26. button_press_event, button_release_event, motion_notify_event,
  27. key_press_event, and key_release_event are called from there.
  28. Attributes
  29. ----------
  30. figure : `matplotlib.figure.Figure`
  31. A high-level Figure instance
  32. """
  33. required_interactive_framework = "macosx"
  34. _timer_cls = TimerMac
  35. def __init__(self, figure):
  36. FigureCanvasBase.__init__(self, figure)
  37. width, height = self.get_width_height()
  38. _macosx.FigureCanvas.__init__(self, width, height)
  39. self._dpi_ratio = 1.0
  40. def _set_device_scale(self, value):
  41. if self._dpi_ratio != value:
  42. # Need the new value in place before setting figure.dpi, which
  43. # will trigger a resize
  44. self._dpi_ratio, old_value = value, self._dpi_ratio
  45. self.figure.dpi = self.figure.dpi / old_value * self._dpi_ratio
  46. def _draw(self):
  47. renderer = self.get_renderer(cleared=self.figure.stale)
  48. if self.figure.stale:
  49. self.figure.draw(renderer)
  50. return renderer
  51. def draw(self):
  52. # docstring inherited
  53. self.draw_idle()
  54. self.flush_events()
  55. # draw_idle is provided by _macosx.FigureCanvas
  56. @cbook.deprecated("3.2", alternative="draw_idle()")
  57. def invalidate(self):
  58. return self.draw_idle()
  59. def blit(self, bbox=None):
  60. self.draw_idle()
  61. def resize(self, width, height):
  62. dpi = self.figure.dpi
  63. width /= dpi
  64. height /= dpi
  65. self.figure.set_size_inches(width * self._dpi_ratio,
  66. height * self._dpi_ratio,
  67. forward=False)
  68. FigureCanvasBase.resize_event(self)
  69. self.draw_idle()
  70. class FigureManagerMac(_macosx.FigureManager, FigureManagerBase):
  71. """
  72. Wrap everything up into a window for the pylab interface
  73. """
  74. def __init__(self, canvas, num):
  75. FigureManagerBase.__init__(self, canvas, num)
  76. title = "Figure %d" % num
  77. _macosx.FigureManager.__init__(self, canvas, title)
  78. if mpl.rcParams['toolbar'] == 'toolbar2':
  79. self.toolbar = NavigationToolbar2Mac(canvas)
  80. else:
  81. self.toolbar = None
  82. if self.toolbar is not None:
  83. self.toolbar.update()
  84. if mpl.is_interactive():
  85. self.show()
  86. self.canvas.draw_idle()
  87. def close(self):
  88. Gcf.destroy(self)
  89. class NavigationToolbar2Mac(_macosx.NavigationToolbar2, NavigationToolbar2):
  90. def __init__(self, canvas):
  91. self.canvas = canvas # Needed by the _macosx __init__.
  92. data_path = cbook._get_data_path('images')
  93. _, tooltips, image_names, _ = zip(*NavigationToolbar2.toolitems)
  94. _macosx.NavigationToolbar2.__init__(
  95. self,
  96. tuple(str(data_path / image_name) + ".pdf"
  97. for image_name in image_names if image_name is not None),
  98. tuple(tooltip for tooltip in tooltips if tooltip is not None))
  99. NavigationToolbar2.__init__(self, canvas)
  100. def draw_rubberband(self, event, x0, y0, x1, y1):
  101. self.canvas.set_rubberband(int(x0), int(y0), int(x1), int(y1))
  102. def release_zoom(self, event):
  103. super().release_zoom(event)
  104. self.canvas.remove_rubberband()
  105. def set_cursor(self, cursor):
  106. _macosx.set_cursor(cursor)
  107. def save_figure(self, *args):
  108. filename = _macosx.choose_save_file('Save the figure',
  109. self.canvas.get_default_filename())
  110. if filename is None: # Cancel
  111. return
  112. self.canvas.figure.savefig(filename)
  113. def prepare_configure_subplots(self):
  114. toolfig = Figure(figsize=(6, 3))
  115. canvas = FigureCanvasMac(toolfig)
  116. toolfig.subplots_adjust(top=0.9)
  117. # Need to keep a reference to the tool.
  118. _tool = SubplotTool(self.canvas.figure, toolfig)
  119. return canvas
  120. def set_message(self, message):
  121. _macosx.NavigationToolbar2.set_message(self, message.encode('utf-8'))
  122. ########################################################################
  123. #
  124. # Now just provide the standard names that backend.__init__ is expecting
  125. #
  126. ########################################################################
  127. @_Backend.export
  128. class _BackendMac(_Backend):
  129. FigureCanvas = FigureCanvasMac
  130. FigureManager = FigureManagerMac
  131. @staticmethod
  132. def trigger_manager_draw(manager):
  133. manager.canvas.draw_idle()
  134. @staticmethod
  135. def mainloop():
  136. _macosx.show()