Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3cfaec1

Browse files
committed
Refactor Pass 2. Refactored Gcf out of all backend code.
1 parent00a2252 commit3cfaec1

File tree

8 files changed

+299
-158
lines changed

8 files changed

+299
-158
lines changed

‎lib/matplotlib/_pylab_helpers.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
importgc
1010
importatexit
1111

12+
frommatplotlibimportis_interactive
1213

1314
deferror_msg(msg):
1415
print(msg,file=sys.stderr)
@@ -35,6 +36,16 @@ class Gcf(object):
3536
_activeQue= []
3637
figs= {}
3738

39+
@classmethod
40+
defadd_figure_manager(cls,manager):
41+
cls.figs[manager.num]=manager
42+
try:# TODO remove once all backends converted to use the new manager.
43+
manager.mpl_connect('window_destroy_event',cls.destroy_cbk)
44+
except:
45+
pass
46+
47+
cls.set_active(manager)
48+
3849
@classmethod
3950
defget_fig_manager(cls,num):
4051
"""
@@ -46,6 +57,49 @@ def get_fig_manager(cls, num):
4657
cls.set_active(manager)
4758
returnmanager
4859

60+
@classmethod
61+
defshow_all(cls,block=None):
62+
"""
63+
Show all figures. If *block* is not None, then
64+
it is a boolean that overrides all other factors
65+
determining whether show blocks by calling mainloop().
66+
The other factors are:
67+
it does not block if run inside ipython's "%pylab" mode
68+
it does not block in interactive mode.
69+
"""
70+
managers=cls.get_all_fig_managers()
71+
ifnotmanagers:
72+
return
73+
74+
formanagerinmanagers:
75+
manager.show()
76+
77+
ifblockisnotNone:
78+
ifblock:
79+
manager.mainloop()
80+
return
81+
82+
frommatplotlibimportpyplot
83+
try:
84+
ipython_pylab=notpyplot.show._needmain
85+
# IPython versions >= 0.10 tack the _needmain
86+
# attribute onto pyplot.show, and always set
87+
# it to False, when in %pylab mode.
88+
ipython_pylab=ipython_pylabandget_backend()!='WebAgg'
89+
# TODO: The above is a hack to get the WebAgg backend
90+
# working with ipython's `%pylab` mode until proper
91+
# integration is implemented.
92+
exceptAttributeError:
93+
ipython_pylab=False
94+
95+
# Leave the following as a separate step in case we
96+
# want to control this behavior with an rcParam.
97+
ifipython_pylab:
98+
block=False
99+
100+
ifnotis_interactive()orget_backend()=='WebAgg':
101+
manager.mainloop()
102+
49103
@classmethod
50104
defdestroy(cls,num):
51105
"""
@@ -134,7 +188,9 @@ def set_active(cls, manager):
134188
ifm!=manager:
135189
cls._activeQue.append(m)
136190
cls._activeQue.append(manager)
137-
cls.figs[manager.num]=manager
138191

192+
@classmethod
193+
defdestroy_cbk(cls,event):
194+
cls.destroy(event.figure_manager.num)
139195

140196
atexit.register(Gcf.destroy_all)

‎lib/matplotlib/backend_bases.py

Lines changed: 35 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
importio
4141

4242
importnumpyasnp
43-
importmatplotlib# temporary )assuming we refactor where marked below)
4443
importmatplotlib.cbookascbook
4544
importmatplotlib.colorsascolors
4645
importmatplotlib.transformsastransforms
@@ -133,6 +132,33 @@ def get_registered_canvas_class(format):
133132
returnbackend_class
134133

135134

135+
classMainLoopBase(object):
136+
"""This gets used as a key maintaining the event loop.
137+
Backends should only need to override begin and end.
138+
It should not matter if this gets used as a singleton or not due to
139+
clever magic.
140+
"""
141+
_instance_count= {}
142+
def__init__(self):
143+
MainLoopBase._instance_count.setdefault(self.__class__,0)
144+
MainLoopBase._instance_count[self.__class__]+=1
145+
146+
defbegin(self):
147+
pass
148+
149+
defend(self):
150+
pass
151+
152+
def__call__(self):
153+
self.begin()
154+
155+
def__del__(self):
156+
MainLoopBase._instance_count[self.__class__]-=1
157+
if (MainLoopBase._instance_count[self.__class__]<=0and
158+
notis_interactive()):
159+
self.end()
160+
161+
136162
classShowBase(object):
137163
"""
138164
Simple base class to generate a show() callable in backends.
@@ -2460,7 +2486,10 @@ def key_press_handler(event, canvas, toolbar=None):
24602486

24612487
# quit the figure (defaut key 'ctrl+w')
24622488
ifevent.keyinquit_keys:
2463-
Gcf.destroy_fig(canvas.figure)
2489+
ifisinstance(canvas.manager.mainloop,MainLoopBase):# If new no Gcf.
2490+
canvas.manager._destroy('window_destroy_event')
2491+
else:
2492+
Gcf.destroy_fig(canvas.figure)
24642493

24652494
iftoolbarisnotNone:
24662495
# home or reset mnemonic (default key 'h', 'home' and 'r')
@@ -2535,20 +2564,16 @@ def key_press_handler(event, canvas, toolbar=None):
25352564
classNonGuiException(Exception):
25362565
pass
25372566

2567+
25382568
classWindowEvent(object):
25392569
def__init__(self,name,window):
25402570
self.name=name
25412571
self.window=window
25422572

2543-
classWindowBase(object):
2544-
def__init__(self,title):
2545-
self._callbacks=cbook.CallbackRegistry()
25462573

2547-
defmpl_connect(self,s,func):
2548-
returnself._callbacks.connect(s,func)
2549-
2550-
defmpl_disconnect(self,cid):
2551-
returnself._callbacks.disconnect(cid)
2574+
classWindowBase(cbook.EventEmitter):
2575+
def__init__(self,title):
2576+
cbook.EventEmitter.__init__(self)
25522577

25532578
defshow(self):
25542579
"""
@@ -2589,112 +2614,12 @@ def add_element_to_window(self, element, expand, fill, padding, from_start=False
25892614
"""
25902615
pass
25912616

2592-
defterminate_backend(self):
2593-
"""Method to terminate the usage of the backend
2594-
"""
2595-
# TODO refactor me out on second pass
2596-
pass
2597-
25982617
defdestroy_event(self,*args):
25992618
s='window_destroy_event'
26002619
event=WindowEvent(s,self)
26012620
self._callbacks.process(s,event)
26022621

26032622

2604-
classFigureManager(object):
2605-
def__init__(self,canvas,num,classes):
2606-
self._classes=classes
2607-
self.canvas=canvas
2608-
canvas.manager=self
2609-
self.num=num
2610-
2611-
self.key_press_handler_id=self.canvas.mpl_connect('key_press_event',
2612-
self.key_press)
2613-
2614-
self.window=classes['Window']('Figure %d'%num)
2615-
self.window.mpl_connect('window_destroy_event',self._destroy)
2616-
2617-
w=int(self.canvas.figure.bbox.width)
2618-
h=int(self.canvas.figure.bbox.height)
2619-
2620-
self.window.add_element_to_window(self.canvas,True,True,0,True)
2621-
2622-
self.toolbar=self._get_toolbar(canvas)
2623-
ifself.toolbarisnotNone:
2624-
h+=self.window.add_element_to_window(self.toolbar,False,False,0)
2625-
2626-
self.window.set_default_size(w,h)
2627-
2628-
# Refactor this? If so, delete import matplotlib from above.
2629-
ifmatplotlib.is_interactive():
2630-
self.window.show()
2631-
2632-
defnotify_axes_change(fig):
2633-
'this will be called whenever the current axes is changed'
2634-
ifself.toolbarisnotNone:self.toolbar.update()
2635-
self.canvas.figure.add_axobserver(notify_axes_change)
2636-
2637-
self.canvas.grab_focus()
2638-
2639-
defkey_press(self,event):
2640-
"""
2641-
Implement the default mpl key bindings defined at
2642-
:ref:`key-event-handling`
2643-
"""
2644-
key_press_handler(event,self.canvas,self.canvas.toolbar)
2645-
2646-
def_destroy(self,event):
2647-
Gcf.destroy(self.num)# TODO refactor me out of here on second pass!
2648-
2649-
defdestroy(self,*args):
2650-
self.window.destroy()
2651-
self.canvas.destroy()
2652-
ifself.toolbar:
2653-
self.toolbar.destroy()
2654-
2655-
# TODO refactor out on second pass
2656-
ifGcf.get_num_fig_managers()==0andnotmatplotlib.is_interactive():
2657-
self.window.terminate_backend()
2658-
2659-
defshow(self):
2660-
self.window.show()
2661-
2662-
deffull_screen_toggle(self):
2663-
self._full_screen_flag=notself._full_screen_flag
2664-
self.window.set_fullscreen(self._full_screen_flag)
2665-
2666-
defresize(self,w,h):
2667-
self.window.resize(w,h)
2668-
2669-
defget_window_title(self):
2670-
"""
2671-
Get the title text of the window containing the figure.
2672-
Return None for non-GUI backends (e.g., a PS backend).
2673-
"""
2674-
returnself.window.get_window_title()
2675-
2676-
defset_window_title(self,title):
2677-
"""
2678-
Set the title text of the window containing the figure. Note that
2679-
this has no effect for non-GUI backends (e.g., a PS backend).
2680-
"""
2681-
self.window.set_window_title(title)
2682-
2683-
defshow_popup(self,msg):
2684-
"""
2685-
Display message in a popup -- GUI only
2686-
"""
2687-
pass
2688-
2689-
def_get_toolbar(self,canvas):
2690-
# must be inited after the window, drawingArea and figure
2691-
# attrs are set
2692-
ifrcParams['toolbar']=='toolbar2':
2693-
toolbar=self._classes['Toolbar2'](canvas,self.window)
2694-
else:
2695-
toolbar=None
2696-
returntoolbar
2697-
26982623
classFigureManagerBase(object):
26992624
"""
27002625
Helper class for pyplot mode, wraps everything up into a neat bundle

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp