You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			135 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Python
		
	
"""
 | 
						|
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()
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    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
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    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()
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    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)
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    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()
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def has_fignum(cls, num):
 | 
						|
        """Return whether figure number *num* exists."""
 | 
						|
        return num in cls.figs
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def get_all_fig_managers(cls):
 | 
						|
        """Return a list of figure managers."""
 | 
						|
        return list(cls.figs.values())
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def get_num_fig_managers(cls):
 | 
						|
        """Return the number of figures being managed."""
 | 
						|
        return len(cls.figs)
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    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
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    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)
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def set_active(cls, manager):
 | 
						|
        """Make *manager* the active manager."""
 | 
						|
        cls.figs[manager.num] = manager
 | 
						|
        cls.figs.move_to_end(manager.num)
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    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)
 |