11from __future__ import division
22"""
33
4- backend_wx .py
4+ backend_wxagg .py
55
66 A wxPython backend for Agg. This uses the GUI widgets written by
77 Jeremy O'Donoghue (jeremy@o-donoghue.com) and the Agg backend by John
88 Hunter (jdhunter@ace.bsd.uchicago.edu)
99
10- Copyright (C) Jeremy O'Donoghue & John Hunter, 2003-4
10+ Copyright (C) 2003-4 Jeremy O'Donoghue & John Hunter
11+ Copyright (C) 2005 Illinois Institute of Technology
1112
1213 License: This work is licensed under the matplotlib license( PSF
1314 compatible). A copy should be included with this source code.
1415
1516"""
1617
17- import sys , os , os .path , math , StringIO
18- from backend_agg import FigureCanvasAgg
19-
20- from backend_wx import FigureManager
21- from backend_wx import FigureManagerWx , FigureCanvasWx , FigureFrameWx , \
22- DEBUG_MSG , NavigationToolbar2Wx
23- from backend_wx import error_msg_wx , draw_if_interactive , show , Toolbar , \
24- backend_version
25- import backend_wx
26-
27- from matplotlib .figure import Figure
28- from matplotlib import rcParams
29- import matplotlib
3018import wx
19+ import matplotlib
20+ from matplotlib .figure import Figure
21+ from matplotlib .transforms import Bbox , Point , Value
3122
23+ from backend_agg import FigureCanvasAgg
24+ import backend_wx
25+ from backend_wx import FigureManager , FigureManagerWx , FigureCanvasWx , \
26+ FigureFrameWx , DEBUG_MSG , NavigationToolbar2Wx , error_msg_wx , \
27+ draw_if_interactive , show , Toolbar , backend_version
3228
3329
3430class FigureFrameWxAgg (FigureFrameWx ):
35-
3631 def get_canvas (self , fig ):
3732 return FigureCanvasWxAgg (self , - 1 , fig )
3833
@@ -45,7 +40,7 @@ def _get_toolbar(self, statbar):
4540 else :
4641 toolbar = None
4742 return toolbar
48-
43+
4944class FigureCanvasWxAgg (FigureCanvasWx ,FigureCanvasAgg ):
5045 """
5146 The FigureCanvas contains the figure and does event handling.
@@ -57,21 +52,47 @@ class FigureCanvasWxAgg(FigureCanvasWx,FigureCanvasAgg):
5752 size.
5853 """
5954
60-
61- def draw (self ):
55+ def draw (self , repaint = True ):
6256 """
63- Render the figure using agg
57+ Render the figure using agg.
6458 """
6559 DEBUG_MSG ("draw()" , 1 , self )
6660 FigureCanvasAgg .draw (self )
67- s = self .tostring_rgb ()
68- w = int (self .renderer .width )
69- h = int (self .renderer .height )
70- image = wx .EmptyImage (w ,h )
71- image .SetData (s )
72- self .bitmap = image .ConvertToBitmap ()
61+
62+ self .bitmap = _convert_agg_to_wx_bitmap (self .get_renderer (), None )
63+ if repaint :
64+ self .gui_repaint ()
65+
66+ def blit (self , bbox = None ):
67+ """
68+ Transfer the region of the agg buffer defined by bbox to the display.
69+ If bbox is None, the entire buffer is transferred.
70+ """
71+ if bbox is None :
72+ self .bitmap = _convert_agg_to_wx_bitmap (self .get_renderer (), None )
73+ self .gui_repaint ()
74+ return
75+
76+ l , b , w , h = bbox .get_bounds ()
77+ r = l + w
78+ t = b + h
79+ x = int (l )
80+ y = int (self .bitmap .GetHeight () - t )
81+
82+ srcBmp = _convert_agg_to_wx_bitmap (self .get_renderer (), bbox )
83+ srcDC = wx .MemoryDC ()
84+ srcDC .SelectObject (srcBmp )
85+
86+ destDC = wx .MemoryDC ()
87+ destDC .SelectObject (self .bitmap )
88+
89+ destDC .BeginDrawing ()
90+ destDC .Blit (x , y , w , h , srcDC , 0 , 0 )
91+ destDC .EndDrawing ()
92+
93+ destDC .SelectObject (wx .NullBitmap )
94+ srcDC .SelectObject (wx .NullBitmap )
7395 self .gui_repaint ()
74-
7596
7697 def print_figure (self , filename , dpi = 150 , facecolor = 'w' ,
7798 edgecolor = 'w' , orientation = 'portrait' ):
@@ -96,6 +117,7 @@ class NavigationToolbar2WxAgg(NavigationToolbar2Wx):
96117 def get_canvas (self , frame , fig ):
97118 return FigureCanvasWxAgg (frame , - 1 , fig )
98119
120+
99121def new_figure_manager (num , * args , ** kwargs ):
100122 """
101123 Create a new figure manager instance
@@ -119,3 +141,96 @@ def new_figure_manager(num, *args, **kwargs):
119141 return figmgr
120142
121143
144+ #
145+ # agg/wxPython image conversion functions
146+ #
147+
148+ def _py_convert_agg_to_wx_image (agg , bbox ):
149+ """
150+ Convert the region of the agg buffer bounded by bbox to a wx.Image. If
151+ bbox is None, the entire buffer is converted.
152+
153+ Note: agg must be a backend_agg.RendererAgg instance.
154+ """
155+ wPx = agg .width
156+ hPx = agg .height
157+ image = wx .EmptyImage (wPx , hPx )
158+ image .SetData (agg .tostring_rgb ())
159+
160+ if bbox is None :
161+ # agg => rgb -> image
162+ return image
163+ else :
164+ # agg => rgb -> image => bitmap => clipped bitmap => image
165+ return wx .ImageFromBitmap (_clipped_image_as_bitmap (image , bbox ))
166+
167+
168+ def _py_convert_agg_to_wx_bitmap (agg , bbox ):
169+ """
170+ Convert the region of the agg buffer bounded by bbox to a wx.Bitmap. If
171+ bbox is None, the entire buffer is converted.
172+
173+ Note: agg must be a backend_agg.RendererAgg instance.
174+ """
175+ if bbox is None :
176+ # agg => rgb -> image => bitmap
177+ return wx .BitmapFromImage (_py_convert_agg_to_wx_image (agg , None ))
178+ else :
179+ # agg => rgb -> image => bitmap => clipped bitmap
180+ return _clipped_image_as_bitmap (
181+ _py_convert_agg_to_wx_image (agg , None ),
182+ bbox )
183+
184+
185+ def _clipped_image_as_bitmap (image , bbox ):
186+ """
187+ Convert the region of a wx.Image described by bbox to a wx.Bitmap.
188+ """
189+ l , b , width , height = bbox .get_bounds ()
190+ r = l + width
191+ t = b + height
192+
193+ srcBmp = wx .BitmapFromImage (image )
194+ srcDC = wx .MemoryDC ()
195+ srcDC .SelectObject (srcBmp )
196+
197+ destBmp = wx .EmptyBitmap (width , height )
198+ destDC = wx .MemoryDC ()
199+ destDC .SelectObject (destBmp )
200+
201+ destDC .BeginDrawing ()
202+ x = int (l )
203+ y = int (image .GetHeight () - t )
204+ destDC .Blit (0 , 0 , width , height , srcDC , x , y )
205+ destDC .EndDrawing ()
206+
207+ srcDC .SelectObject (wx .NullBitmap )
208+ destDC .SelectObject (wx .NullBitmap )
209+
210+ return destBmp
211+
212+
213+ def _use_accelerator (state ):
214+ """
215+ Enable or disable the WXAgg accelerator, if it is present.
216+ """
217+ global _convert_agg_to_wx_image
218+ global _convert_agg_to_wx_bitmap
219+
220+ if state and _wxagg is not None :
221+ _convert_agg_to_wx_image = _wxagg .convert_agg_to_wx_image
222+ _convert_agg_to_wx_bitmap = _wxagg .convert_agg_to_wx_bitmap
223+ else :
224+ _convert_agg_to_wx_image = _py_convert_agg_to_wx_image
225+ _convert_agg_to_wx_bitmap = _py_convert_agg_to_wx_bitmap
226+
227+
228+ # try to load the WXAgg accelerator
229+ try :
230+ import _wxagg
231+ except ImportError :
232+ _wxagg = None
233+
234+ # if it's present, use it
235+ _use_accelerator (True )
236+
0 commit comments