Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 97a86f7

Browse files
Merge branch 'master' of https://github.com/matplotlib/matplotlib into wx-update-examples
2 parents ffd500c + 0e07bdd commit 97a86f7

File tree

5 files changed

+168
-129
lines changed

5 files changed

+168
-129
lines changed
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Cairo rendering for Qt canvases
2-
-------------------------------
1+
Cairo rendering for Qt and WX canvases
2+
--------------------------------------
33

4-
The new ``Qt4Cairo`` and ``Qt5Cairo`` backends allow Qt canvases to use Cairo
5-
rendering instead of Agg.
4+
The new ``Qt4Cairo``, ``Qt5Cairo``, and ``WXCairo`` backends allow Qt and Wx
5+
canvases to use Cairo rendering instead of Agg.

lib/matplotlib/backends/backend_wx.py

Lines changed: 106 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ def get_wxcolour(self, color):
548548
alpha=int(a))
549549

550550

551-
class FigureCanvasWx(FigureCanvasBase, wx.Panel):
551+
class _FigureCanvasWxBase(FigureCanvasBase, wx.Panel):
552552
"""
553553
The FigureCanvas contains the figure and does event handling.
554554
@@ -709,23 +709,11 @@ def draw_idle(self):
709709
"""
710710
DEBUG_MSG("draw_idle()", 1, self)
711711
self._isDrawn = False # Force redraw
712-
713712
# Triggering a paint event is all that is needed to defer drawing
714713
# until later. The platform will send the event when it thinks it is
715714
# a good time (usually as soon as there are no other events pending).
716715
self.Refresh(eraseBackground=False)
717716

718-
def draw(self, drawDC=None):
719-
"""
720-
Render the figure using RendererWx instance renderer, or using a
721-
previously defined renderer if none is specified.
722-
"""
723-
DEBUG_MSG("draw()", 1, self)
724-
self.renderer = RendererWx(self.bitmap, self.figure.dpi)
725-
self.figure.draw(self.renderer)
726-
self._isDrawn = True
727-
self.gui_repaint(drawDC=drawDC)
728-
729717
def new_timer(self, *args, **kwargs):
730718
"""
731719
Creates a new backend-specific subclass of
@@ -838,94 +826,13 @@ def gui_repaint(self, drawDC=None, origin='WX'):
838826
filetypes['xpm'] = 'X pixmap'
839827

840828
def print_figure(self, filename, *args, **kwargs):
841-
# Use pure Agg renderer to draw
842-
FigureCanvasBase.print_figure(self, filename, *args, **kwargs)
843-
# Restore the current view; this is needed because the
844-
# artist contains methods rely on particular attributes
845-
# of the rendered figure for determining things like
846-
# bounding boxes.
847-
if self._isDrawn:
848-
self.draw()
849-
850-
def print_bmp(self, filename, *args, **kwargs):
851-
return self._print_image(filename, wx.BITMAP_TYPE_BMP, *args, **kwargs)
852-
853-
if not _has_pil:
854-
def print_jpeg(self, filename, *args, **kwargs):
855-
return self._print_image(filename, wx.BITMAP_TYPE_JPEG,
856-
*args, **kwargs)
857-
print_jpg = print_jpeg
858-
859-
def print_pcx(self, filename, *args, **kwargs):
860-
return self._print_image(filename, wx.BITMAP_TYPE_PCX, *args, **kwargs)
861-
862-
def print_png(self, filename, *args, **kwargs):
863-
return self._print_image(filename, wx.BITMAP_TYPE_PNG, *args, **kwargs)
864-
865-
if not _has_pil:
866-
def print_tiff(self, filename, *args, **kwargs):
867-
return self._print_image(filename, wx.BITMAP_TYPE_TIF,
868-
*args, **kwargs)
869-
print_tif = print_tiff
870-
871-
def print_xpm(self, filename, *args, **kwargs):
872-
return self._print_image(filename, wx.BITMAP_TYPE_XPM, *args, **kwargs)
873-
874-
def _print_image(self, filename, filetype, *args, **kwargs):
875-
origBitmap = self.bitmap
876-
877-
l, b, width, height = self.figure.bbox.bounds
878-
width = int(math.ceil(width))
879-
height = int(math.ceil(height))
880-
881-
self.bitmap = wxc.EmptyBitmap(width, height)
882-
883-
renderer = RendererWx(self.bitmap, self.figure.dpi)
884-
885-
gc = renderer.new_gc()
886-
887-
self.figure.draw(renderer)
888-
889-
# image is the object that we call SaveFile on.
890-
image = self.bitmap
891-
# set the JPEG quality appropriately. Unfortunately, it is only
892-
# possible to set the quality on a wx.Image object. So if we
893-
# are saving a JPEG, convert the wx.Bitmap to a wx.Image,
894-
# and set the quality.
895-
if filetype == wx.BITMAP_TYPE_JPEG:
896-
jpeg_quality = kwargs.get('quality',
897-
rcParams['savefig.jpeg_quality'])
898-
image = self.bitmap.ConvertToImage()
899-
image.SetOption(wx.IMAGE_OPTION_QUALITY, str(jpeg_quality))
900-
901-
# Now that we have rendered into the bitmap, save it
902-
# to the appropriate file type and clean up
903-
if isinstance(filename, six.string_types):
904-
if not image.SaveFile(filename, filetype):
905-
DEBUG_MSG('print_figure() file save error', 4, self)
906-
raise RuntimeError(
907-
'Could not save figure to %s\n' %
908-
(filename))
909-
elif is_writable_file_like(filename):
910-
if not isinstance(image, wx.Image):
911-
image = image.ConvertToImage()
912-
if not image.SaveStream(filename, filetype):
913-
DEBUG_MSG('print_figure() file save error', 4, self)
914-
raise RuntimeError(
915-
'Could not save figure to %s\n' %
916-
(filename))
917-
918-
# Restore everything to normal
919-
self.bitmap = origBitmap
920-
921-
# Note: draw is required here since bits of state about the
922-
# last renderer are strewn about the artist draw methods. Do
923-
# not remove the draw without first verifying that these have
924-
# been cleaned up. The artist contains() methods will fail
925-
# otherwise.
829+
super(_FigureCanvasWxBase, self).print_figure(
830+
filename, *args, **kwargs)
831+
# Restore the current view; this is needed because the artist contains
832+
# methods rely on particular attributes of the rendered figure for
833+
# determining things like bounding boxes.
926834
if self._isDrawn:
927835
self.draw()
928-
self.Refresh()
929836

930837
def _onPaint(self, evt):
931838
"""
@@ -1007,14 +914,16 @@ def _get_key(self, evt):
1007914
def _onKeyDown(self, evt):
1008915
"""Capture key press."""
1009916
key = self._get_key(evt)
1010-
evt.Skip()
1011917
FigureCanvasBase.key_press_event(self, key, guiEvent=evt)
918+
if self:
919+
evt.Skip()
1012920

1013921
def _onKeyUp(self, evt):
1014922
"""Release key."""
1015923
key = self._get_key(evt)
1016-
evt.Skip()
1017924
FigureCanvasBase.key_release_event(self, key, guiEvent=evt)
925+
if self:
926+
evt.Skip()
1018927

1019928
def _set_capture(self, capture=True):
1020929
"""control wx mouse capture """
@@ -1152,6 +1061,101 @@ def _onEnter(self, evt):
11521061
FigureCanvasBase.enter_notify_event(self, guiEvent=evt)
11531062

11541063

1064+
class FigureCanvasWx(_FigureCanvasWxBase):
1065+
# Rendering to a Wx canvas using the deprecated Wx renderer.
1066+
1067+
def draw(self, drawDC=None):
1068+
"""
1069+
Render the figure using RendererWx instance renderer, or using a
1070+
previously defined renderer if none is specified.
1071+
"""
1072+
DEBUG_MSG("draw()", 1, self)
1073+
self.renderer = RendererWx(self.bitmap, self.figure.dpi)
1074+
self.figure.draw(self.renderer)
1075+
self._isDrawn = True
1076+
self.gui_repaint(drawDC=drawDC)
1077+
1078+
def print_bmp(self, filename, *args, **kwargs):
1079+
return self._print_image(filename, wx.BITMAP_TYPE_BMP, *args, **kwargs)
1080+
1081+
if not _has_pil:
1082+
def print_jpeg(self, filename, *args, **kwargs):
1083+
return self._print_image(filename, wx.BITMAP_TYPE_JPEG,
1084+
*args, **kwargs)
1085+
print_jpg = print_jpeg
1086+
1087+
def print_pcx(self, filename, *args, **kwargs):
1088+
return self._print_image(filename, wx.BITMAP_TYPE_PCX, *args, **kwargs)
1089+
1090+
def print_png(self, filename, *args, **kwargs):
1091+
return self._print_image(filename, wx.BITMAP_TYPE_PNG, *args, **kwargs)
1092+
1093+
if not _has_pil:
1094+
def print_tiff(self, filename, *args, **kwargs):
1095+
return self._print_image(filename, wx.BITMAP_TYPE_TIF,
1096+
*args, **kwargs)
1097+
print_tif = print_tiff
1098+
1099+
def print_xpm(self, filename, *args, **kwargs):
1100+
return self._print_image(filename, wx.BITMAP_TYPE_XPM, *args, **kwargs)
1101+
1102+
def _print_image(self, filename, filetype, *args, **kwargs):
1103+
origBitmap = self.bitmap
1104+
1105+
l, b, width, height = self.figure.bbox.bounds
1106+
width = int(math.ceil(width))
1107+
height = int(math.ceil(height))
1108+
1109+
self.bitmap = wxc.EmptyBitmap(width, height)
1110+
1111+
renderer = RendererWx(self.bitmap, self.figure.dpi)
1112+
1113+
gc = renderer.new_gc()
1114+
1115+
self.figure.draw(renderer)
1116+
1117+
# image is the object that we call SaveFile on.
1118+
image = self.bitmap
1119+
# set the JPEG quality appropriately. Unfortunately, it is only
1120+
# possible to set the quality on a wx.Image object. So if we
1121+
# are saving a JPEG, convert the wx.Bitmap to a wx.Image,
1122+
# and set the quality.
1123+
if filetype == wx.BITMAP_TYPE_JPEG:
1124+
jpeg_quality = kwargs.get('quality',
1125+
rcParams['savefig.jpeg_quality'])
1126+
image = self.bitmap.ConvertToImage()
1127+
image.SetOption(wx.IMAGE_OPTION_QUALITY, str(jpeg_quality))
1128+
1129+
# Now that we have rendered into the bitmap, save it
1130+
# to the appropriate file type and clean up
1131+
if isinstance(filename, six.string_types):
1132+
if not image.SaveFile(filename, filetype):
1133+
DEBUG_MSG('print_figure() file save error', 4, self)
1134+
raise RuntimeError(
1135+
'Could not save figure to %s\n' %
1136+
(filename))
1137+
elif is_writable_file_like(filename):
1138+
if not isinstance(image, wx.Image):
1139+
image = image.ConvertToImage()
1140+
if not image.SaveStream(filename, filetype):
1141+
DEBUG_MSG('print_figure() file save error', 4, self)
1142+
raise RuntimeError(
1143+
'Could not save figure to %s\n' %
1144+
(filename))
1145+
1146+
# Restore everything to normal
1147+
self.bitmap = origBitmap
1148+
1149+
# Note: draw is required here since bits of state about the
1150+
# last renderer are strewn about the artist draw methods. Do
1151+
# not remove the draw without first verifying that these have
1152+
# been cleaned up. The artist contains() methods will fail
1153+
# otherwise.
1154+
if self._isDrawn:
1155+
self.draw()
1156+
self.Refresh()
1157+
1158+
11551159
########################################################################
11561160
#
11571161
# The following functions and classes are for pylab compatibility
@@ -1228,7 +1232,7 @@ def _get_toolbar(self, statbar):
12281232
return toolbar
12291233

12301234
def get_canvas(self, fig):
1231-
return FigureCanvasWx(self, -1, fig)
1235+
return type(self.canvas)(self, -1, fig)
12321236

12331237
def get_figure_manager(self):
12341238
DEBUG_MSG("get_figure_manager()", 1, self)

lib/matplotlib/backends/backend_wxagg.py

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,19 @@
66
import wx
77

88
import matplotlib
9+
from .. import cbook
910
from . import wx_compat as wxc
10-
from . import backend_wx
1111
from .backend_agg import FigureCanvasAgg
1212
from .backend_wx import (
13-
_BackendWx, FigureCanvasWx, FigureFrameWx, NavigationToolbar2Wx, DEBUG_MSG)
13+
_BackendWx, _FigureCanvasWxBase, FigureFrameWx, NavigationToolbar2Wx)
1414

1515

1616
class FigureFrameWxAgg(FigureFrameWx):
1717
def get_canvas(self, fig):
1818
return FigureCanvasWxAgg(self, -1, fig)
1919

20-
def _get_toolbar(self, statbar):
21-
if matplotlib.rcParams['toolbar'] == 'toolbar2':
22-
toolbar = NavigationToolbar2WxAgg(self.canvas)
23-
toolbar.set_status_bar(statbar)
24-
else:
25-
toolbar = None
26-
return toolbar
2720

28-
29-
class FigureCanvasWxAgg(FigureCanvasAgg, FigureCanvasWx):
21+
class FigureCanvasWxAgg(FigureCanvasAgg, _FigureCanvasWxBase):
3022
"""
3123
The FigureCanvas contains the figure and does event handling.
3224
@@ -41,7 +33,6 @@ def draw(self, drawDC=None):
4133
"""
4234
Render the figure using agg.
4335
"""
44-
DEBUG_MSG("draw()", 1, self)
4536
FigureCanvasAgg.draw(self)
4637

4738
self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
@@ -79,17 +70,8 @@ def blit(self, bbox=None):
7970

8071
filetypes = FigureCanvasAgg.filetypes
8172

82-
def print_figure(self, filename, *args, **kwargs):
83-
# Use pure Agg renderer to draw
84-
FigureCanvasAgg.print_figure(self, filename, *args, **kwargs)
85-
# Restore the current view; this is needed because the
86-
# artist contains methods rely on particular attributes
87-
# of the rendered figure for determining things like
88-
# bounding boxes.
89-
if self._isDrawn:
90-
self.draw()
91-
9273

74+
@cbook.deprecated("2.2")
9375
class NavigationToolbar2WxAgg(NavigationToolbar2Wx):
9476
def get_canvas(self, frame, fig):
9577
return FigureCanvasWxAgg(frame, -1, fig)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from __future__ import (absolute_import, division, print_function,
2+
unicode_literals)
3+
4+
import six
5+
6+
import wx
7+
8+
from .backend_cairo import cairo, FigureCanvasCairo, RendererCairo
9+
from .backend_wx import (
10+
_BackendWx, _FigureCanvasWxBase, FigureFrameWx, NavigationToolbar2Wx)
11+
from . import wx_compat as wxc
12+
13+
14+
class FigureFrameWxCairo(FigureFrameWx):
15+
def get_canvas(self, fig):
16+
return FigureCanvasWxCairo(self, -1, fig)
17+
18+
19+
class FigureCanvasWxCairo(_FigureCanvasWxBase, FigureCanvasCairo):
20+
"""
21+
The FigureCanvas contains the figure and does event handling.
22+
23+
In the wxPython backend, it is derived from wxPanel, and (usually) lives
24+
inside a frame instantiated by a FigureManagerWx. The parent window
25+
probably implements a wxSizer to control the displayed control size - but
26+
we give a hint as to our preferred minimum size.
27+
"""
28+
29+
def __init__(self, parent, id, figure):
30+
# _FigureCanvasWxBase should be fixed to have the same signature as
31+
# every other FigureCanvas and use cooperative inheritance, but in the
32+
# meantime the following will make do.
33+
_FigureCanvasWxBase.__init__(self, parent, id, figure)
34+
FigureCanvasCairo.__init__(self, figure)
35+
self._renderer = RendererCairo(self.figure.dpi)
36+
37+
def draw(self, drawDC=None):
38+
width = int(self.figure.bbox.width)
39+
height = int(self.figure.bbox.height)
40+
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
41+
self._renderer.set_ctx_from_surface(surface)
42+
self._renderer.set_width_height(width, height)
43+
self.figure.draw(self._renderer)
44+
buf = surface.get_data()
45+
self.bitmap = wxc.BitmapFromBuffer(width, height, buf)
46+
self._isDrawn = True
47+
self.gui_repaint(drawDC=drawDC, origin='WXCairo')
48+
49+
50+
@_BackendWx.export
51+
class _BackendWxCairo(_BackendWx):
52+
FigureCanvas = FigureCanvasWxCairo
53+
_frame_class = FigureFrameWxCairo

lib/matplotlib/rcsetup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo',
4545
'TkAgg',
4646
'WebAgg',
47-
'WX', 'WXAgg']
47+
'WX', 'WXAgg', 'WXCairo']
4848
non_interactive_bk = ['agg', 'cairo', 'gdk',
4949
'pdf', 'pgf', 'ps', 'svg', 'template']
5050
all_backends = interactive_bk + non_interactive_bk

0 commit comments

Comments
 (0)