11"""
2- Manage figures for pyplot interface.
2+ Manage figures for the pyplot interface.
33"""
44
55import atexit
6+ from collections import OrderedDict
67import gc
78
89
910class Gcf (object ):
1011 """
11- Singleton to manage a set of integer-numbered figures.
12-
13- This class is never instantiated; it consists of two class
14- attributes (a list and a dictionary), and a set of static
15- methods that operate on those attributes, accessing them
16- directly as class attributes.
17-
18- Attributes:
19-
20- *figs*:
21- dictionary of the form {*num*: *manager*, ...}
22-
23- *_activeQue*:
24- list of *managers*, with active one at the end
25-
12+ Singleton to handle a set of "numbered" figures and managers, and keep
13+ track of an "active" figure and manager.
14+
15+ This class is never instantiated; it consists of an `OrderedDict` mapping
16+ figure/manager numbers to managers, and a set of class methods that
17+ manipulate this `OrderedDict`.
18+
19+ Note that figure/manager "numbers" should be thought of as "labels"; in
20+ particular they can actually be any hashable value. Moreover, even though
21+ the number is only stored on the manager, we also use the term "figure
22+ number" for the number of the manager associated with a figure.
23+
24+ Attributes
25+ ----------
26+ figs : OrderedDict
27+ `OrderedDict` mapping numbers to managers; the active manager is at the
28+ end.
2629 """
27- _activeQue = []
28- figs = {}
30+
31+ figs = OrderedDict ()
2932
3033 @classmethod
3134 def get_fig_manager (cls , num ):
3235 """
33- If figure manager *num* exists, make it the active
34- figure and return the manager; otherwise return *None*.
36+ If manager number *num* exists, make it the active one and return it;
37+ otherwise return *None*.
3538 """
3639 manager = cls .figs .get (num , None )
3740 if manager is not None :
@@ -41,90 +44,73 @@ def get_fig_manager(cls, num):
4144 @classmethod
4245 def destroy (cls , num ):
4346 """
44- Try to remove all traces of figure *num*.
47+ Destroy figure number *num*.
4548
46- In the interactive backends, this is bound to the
47- window "destroy" and "delete" events.
49+ In the interactive backends, this is bound to the window "destroy" and
50+ "delete" events.
4851 """
4952 if not cls .has_fignum (num ):
5053 return
51- manager = cls .figs [ num ]
54+ manager = cls .figs . pop ( num )
5255 manager .canvas .mpl_disconnect (manager ._cidgcf )
53- cls ._activeQue .remove (manager )
54- del cls .figs [num ]
5556 manager .destroy ()
5657 gc .collect (1 )
5758
5859 @classmethod
5960 def destroy_fig (cls , fig ):
60- "*fig* is a Figure instance "
61- num = next (( manager . num for manager in cls . figs . values ( )
62- if manager . canvas . figure == fig ) , None )
63- if num is not None :
64- cls .destroy (num )
61+ """Destroy figure *fig*."" "
62+ canvas = getattr ( fig , "canvas" , None )
63+ manager = getattr ( canvas , "manager" , None )
64+ num = getattr ( manager , "num" , None )
65+ cls .destroy (num )
6566
6667 @classmethod
6768 def destroy_all (cls ):
68- # this is need to ensure that gc is available in corner cases
69- # where modules are being torn down after install with easy_install
70- import gc # noqa
69+ """Destroy all figures."""
70+ # Reimport gc in case the module globals have already been removed
71+ # during interpreter shutdown.
72+ import gc
7173 for manager in list (cls .figs .values ()):
7274 manager .canvas .mpl_disconnect (manager ._cidgcf )
7375 manager .destroy ()
74-
75- cls ._activeQue = []
7676 cls .figs .clear ()
7777 gc .collect (1 )
7878
7979 @classmethod
8080 def has_fignum (cls , num ):
81- """
82- Return *True* if figure *num* exists.
83- """
81+ """Return whether figure number *num* exists."""
8482 return num in cls .figs
8583
8684 @classmethod
8785 def get_all_fig_managers (cls ):
88- """
89- Return a list of figure managers.
90- """
86+ """Return a list of figure managers."""
9187 return list (cls .figs .values ())
9288
9389 @classmethod
9490 def get_num_fig_managers (cls ):
95- """
96- Return the number of figures being managed.
97- """
91+ """Return the number of figures being managed."""
9892 return len (cls .figs )
9993
10094 @classmethod
10195 def get_active (cls ):
102- """
103- Return the manager of the active figure, or *None*.
104- """
105- if len (cls ._activeQue ) == 0 :
106- return None
107- else :
108- return cls ._activeQue [- 1 ]
96+ """Return the active manager, or *None* if there is no manager."""
97+ return next (reversed (cls .figs .values ())) if cls .figs else None
10998
11099 @classmethod
111100 def set_active (cls , manager ):
112- """
113- Make the figure corresponding to *manager* the active one.
114- """
115- oldQue = cls ._activeQue [:]
116- cls ._activeQue = [m for m in oldQue if m != manager ]
117- cls ._activeQue .append (manager )
101+ """Make *manager* the active manager."""
118102 cls .figs [manager .num ] = manager
103+ cls .figs .move_to_end (manager .num )
119104
120105 @classmethod
121106 def draw_all (cls , force = False ):
122107 """
123- Redraw all figures registered with the pyplot
124- state machine .
108+ Redraw all stale managed figures, or, if *force* is True, all managed
109+ figures .
125110 """
126- for f_mgr in cls .get_all_fig_managers ():
127- if force or f_mgr .canvas .figure .stale :
128- f_mgr .canvas .draw_idle ()
111+ for manager in cls .get_all_fig_managers ():
112+ if force or manager .canvas .figure .stale :
113+ manager .canvas .draw_idle ()
114+
129115
130116atexit .register (Gcf .destroy_all )
0 commit comments