_pylab_helpers.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. """
  2. Manage figures for pyplot interface.
  3. """
  4. import atexit
  5. import gc
  6. class Gcf:
  7. """
  8. Singleton to manage a set of integer-numbered figures.
  9. This class is never instantiated; it consists of two class
  10. attributes (a list and a dictionary), and a set of static
  11. methods that operate on those attributes, accessing them
  12. directly as class attributes.
  13. Attributes
  14. ----------
  15. figs
  16. dictionary of the form {*num*: *manager*, ...}
  17. _activeQue
  18. list of *managers*, with active one at the end
  19. """
  20. _activeQue = []
  21. figs = {}
  22. @classmethod
  23. def get_fig_manager(cls, num):
  24. """
  25. If figure manager *num* exists, make it the active
  26. figure and return the manager; otherwise return *None*.
  27. """
  28. manager = cls.figs.get(num, None)
  29. if manager is not None:
  30. cls.set_active(manager)
  31. return manager
  32. @classmethod
  33. def destroy(cls, num):
  34. """
  35. Try to remove all traces of figure *num*.
  36. In the interactive backends, this is bound to the
  37. window "destroy" and "delete" events.
  38. """
  39. if not cls.has_fignum(num):
  40. return
  41. manager = cls.figs[num]
  42. manager.canvas.mpl_disconnect(manager._cidgcf)
  43. cls._activeQue.remove(manager)
  44. del cls.figs[num]
  45. manager.destroy()
  46. gc.collect(1)
  47. @classmethod
  48. def destroy_fig(cls, fig):
  49. "*fig* is a Figure instance"
  50. num = next((manager.num for manager in cls.figs.values()
  51. if manager.canvas.figure == fig), None)
  52. if num is not None:
  53. cls.destroy(num)
  54. @classmethod
  55. def destroy_all(cls):
  56. # this is need to ensure that gc is available in corner cases
  57. # where modules are being torn down after install with easy_install
  58. import gc # noqa
  59. for manager in list(cls.figs.values()):
  60. manager.canvas.mpl_disconnect(manager._cidgcf)
  61. manager.destroy()
  62. cls._activeQue = []
  63. cls.figs.clear()
  64. gc.collect(1)
  65. @classmethod
  66. def has_fignum(cls, num):
  67. """
  68. Return *True* if figure *num* exists.
  69. """
  70. return num in cls.figs
  71. @classmethod
  72. def get_all_fig_managers(cls):
  73. """
  74. Return a list of figure managers.
  75. """
  76. return list(cls.figs.values())
  77. @classmethod
  78. def get_num_fig_managers(cls):
  79. """
  80. Return the number of figures being managed.
  81. """
  82. return len(cls.figs)
  83. @classmethod
  84. def get_active(cls):
  85. """
  86. Return the manager of the active figure, or *None*.
  87. """
  88. if len(cls._activeQue) == 0:
  89. return None
  90. else:
  91. return cls._activeQue[-1]
  92. @classmethod
  93. def set_active(cls, manager):
  94. """
  95. Make the figure corresponding to *manager* the active one.
  96. """
  97. oldQue = cls._activeQue[:]
  98. cls._activeQue = [m for m in oldQue if m != manager]
  99. cls._activeQue.append(manager)
  100. cls.figs[manager.num] = manager
  101. @classmethod
  102. def draw_all(cls, force=False):
  103. """
  104. Redraw all figures registered with the pyplot
  105. state machine.
  106. """
  107. for f_mgr in cls.get_all_fig_managers():
  108. if force or f_mgr.canvas.figure.stale:
  109. f_mgr.canvas.draw_idle()
  110. atexit.register(Gcf.destroy_all)