Spaces:
Running
Running
| """ | |
| Manage figures for the pyplot interface. | |
| """ | |
| import atexit | |
| from collections import OrderedDict | |
| class Gcf: | |
| """ | |
| Singleton to maintain the relation between figures and their managers, and | |
| keep track of and "active" figure and manager. | |
| The canvas of a figure created through pyplot is associated with a figure | |
| manager, which handles the interaction between the figure and the backend. | |
| pyplot keeps track of figure managers using an identifier, the "figure | |
| number" or "manager number" (which can actually be any hashable value); | |
| this number is available as the :attr:`number` attribute of the manager. | |
| This class is never instantiated; it consists of an `OrderedDict` mapping | |
| figure/manager numbers to managers, and a set of class methods that | |
| manipulate this `OrderedDict`. | |
| Attributes | |
| ---------- | |
| figs : OrderedDict | |
| `OrderedDict` mapping numbers to managers; the active manager is at the | |
| end. | |
| """ | |
| figs = OrderedDict() | |
| def get_fig_manager(cls, num): | |
| """ | |
| If manager number *num* exists, make it the active one and return it; | |
| otherwise return *None*. | |
| """ | |
| manager = cls.figs.get(num, None) | |
| if manager is not None: | |
| cls.set_active(manager) | |
| return manager | |
| def destroy(cls, num): | |
| """ | |
| Destroy manager *num* -- either a manager instance or a manager number. | |
| In the interactive backends, this is bound to the window "destroy" and | |
| "delete" events. | |
| It is recommended to pass a manager instance, to avoid confusion when | |
| two managers share the same number. | |
| """ | |
| if all(hasattr(num, attr) for attr in ["num", "destroy"]): | |
| manager = num | |
| if cls.figs.get(manager.num) is manager: | |
| cls.figs.pop(manager.num) | |
| else: | |
| try: | |
| manager = cls.figs.pop(num) | |
| except KeyError: | |
| return | |
| if hasattr(manager, "_cidgcf"): | |
| manager.canvas.mpl_disconnect(manager._cidgcf) | |
| manager.destroy() | |
| def destroy_fig(cls, fig): | |
| """Destroy figure *fig*.""" | |
| num = next((manager.num for manager in cls.figs.values() | |
| if manager.canvas.figure == fig), None) | |
| if num is not None: | |
| cls.destroy(num) | |
| def destroy_all(cls): | |
| """Destroy all figures.""" | |
| for manager in list(cls.figs.values()): | |
| manager.canvas.mpl_disconnect(manager._cidgcf) | |
| manager.destroy() | |
| cls.figs.clear() | |
| def has_fignum(cls, num): | |
| """Return whether figure number *num* exists.""" | |
| return num in cls.figs | |
| def get_all_fig_managers(cls): | |
| """Return a list of figure managers.""" | |
| return list(cls.figs.values()) | |
| def get_num_fig_managers(cls): | |
| """Return the number of figures being managed.""" | |
| return len(cls.figs) | |
| def get_active(cls): | |
| """Return the active manager, or *None* if there is no manager.""" | |
| return next(reversed(cls.figs.values())) if cls.figs else None | |
| def _set_new_active_manager(cls, manager): | |
| """Adopt *manager* into pyplot and make it the active manager.""" | |
| if not hasattr(manager, "_cidgcf"): | |
| manager._cidgcf = manager.canvas.mpl_connect( | |
| "button_press_event", lambda event: cls.set_active(manager)) | |
| fig = manager.canvas.figure | |
| fig._number = manager.num | |
| label = fig.get_label() | |
| if label: | |
| manager.set_window_title(label) | |
| cls.set_active(manager) | |
| def set_active(cls, manager): | |
| """Make *manager* the active manager.""" | |
| cls.figs[manager.num] = manager | |
| cls.figs.move_to_end(manager.num) | |
| def draw_all(cls, force=False): | |
| """ | |
| Redraw all stale managed figures, or, if *force* is True, all managed | |
| figures. | |
| """ | |
| for manager in cls.get_all_fig_managers(): | |
| if force or manager.canvas.figure.stale: | |
| manager.canvas.draw_idle() | |
| atexit.register(Gcf.destroy_all) | |