14
14
import sys
15
15
import weakref
16
16
17
- import numpy as np
18
- import PIL .Image
19
-
20
17
import matplotlib as mpl
21
18
from matplotlib .backend_bases import (
22
19
_Backend , FigureCanvasBase , FigureManagerBase ,
30
27
from matplotlib .transforms import Affine2D
31
28
32
29
import wx
30
+ import wx .svg
33
31
34
32
_log = logging .getLogger (__name__ )
35
33
@@ -473,10 +471,8 @@ def __init__(self, parent, id, figure=None):
473
471
FigureCanvasBase .__init__ (self , figure )
474
472
w , h = map (math .ceil , self .figure .bbox .size )
475
473
# Set preferred window size hint - helps the sizer, if one is connected
476
- wx .Panel .__init__ (self , parent , id , size = wx .Size (w , h ))
477
- # Create the drawing bitmap
478
- self .bitmap = wx .Bitmap (w , h )
479
- _log .debug ("%s - __init__() - bitmap w:%d h:%d" , type (self ), w , h )
474
+ wx .Panel .__init__ (self , parent , id , size = parent .FromDIP (wx .Size (w , h )))
475
+ self .bitmap = None
480
476
self ._isDrawn = False
481
477
self ._rubberband_rect = None
482
478
self ._rubberband_pen_black = wx .Pen ('BLACK' , 1 , wx .PENSTYLE_SHORT_DASH )
@@ -524,6 +520,12 @@ def Copy_to_Clipboard(self, event=None):
524
520
wx .TheClipboard .Flush ()
525
521
wx .TheClipboard .Close ()
526
522
523
+ def _update_device_pixel_ratio (self , * args , ** kwargs ):
524
+ # We need to be careful in cases with mixed resolution displays if
525
+ # device_pixel_ratio changes.
526
+ if self ._set_device_pixel_ratio (self .GetDPIScaleFactor ()):
527
+ self .draw ()
528
+
527
529
def draw_idle (self ):
528
530
# docstring inherited
529
531
_log .debug ("%s - draw_idle()" , type (self ))
@@ -631,7 +633,7 @@ def _on_size(self, event):
631
633
In this application we attempt to resize to fit the window, so it
632
634
is better to take the performance hit and redraw the whole window.
633
635
"""
634
-
636
+ self . _update_device_pixel_ratio ()
635
637
_log .debug ("%s - _on_size()" , type (self ))
636
638
sz = self .GetParent ().GetSizer ()
637
639
if sz :
@@ -655,9 +657,10 @@ def _on_size(self, event):
655
657
return # Empty figure
656
658
657
659
# Create a new, correctly sized bitmap
658
- self .bitmap = wx .Bitmap (self ._width , self ._height )
659
-
660
660
dpival = self .figure .dpi
661
+ if not wx .Platform == '__WXMSW__' :
662
+ scale = self .GetDPIScaleFactor ()
663
+ dpival /= scale
661
664
winch = self ._width / dpival
662
665
hinch = self ._height / dpival
663
666
self .figure .set_size_inches (winch , hinch , forward = False )
@@ -712,7 +715,11 @@ def _mpl_coords(self, pos=None):
712
715
else :
713
716
x , y = pos .X , pos .Y
714
717
# flip y so y=0 is bottom of canvas
715
- return x , self .figure .bbox .height - y
718
+ if not wx .Platform == '__WXMSW__' :
719
+ scale = self .GetDPIScaleFactor ()
720
+ return x * scale , self .figure .bbox .height - y * scale
721
+ else :
722
+ return x , self .figure .bbox .height - y
716
723
717
724
def _on_key_down (self , event ):
718
725
"""Capture key press."""
@@ -898,8 +905,8 @@ def __init__(self, num, fig, *, canvas_class):
898
905
# On Windows, canvas sizing must occur after toolbar addition;
899
906
# otherwise the toolbar further resizes the canvas.
900
907
w , h = map (math .ceil , fig .bbox .size )
901
- self .canvas .SetInitialSize (wx .Size (w , h ))
902
- self .canvas .SetMinSize (( 2 , 2 ))
908
+ self .canvas .SetInitialSize (self . FromDIP ( wx .Size (w , h ) ))
909
+ self .canvas .SetMinSize (self . FromDIP ( wx . Size ( 2 , 2 ) ))
903
910
self .canvas .SetFocus ()
904
911
905
912
self .Fit ()
@@ -1017,9 +1024,6 @@ def _set_frame_icon(frame):
1017
1024
class NavigationToolbar2Wx (NavigationToolbar2 , wx .ToolBar ):
1018
1025
def __init__ (self , canvas , coordinates = True , * , style = wx .TB_BOTTOM ):
1019
1026
wx .ToolBar .__init__ (self , canvas .GetParent (), - 1 , style = style )
1020
-
1021
- if 'wxMac' in wx .PlatformInfo :
1022
- self .SetToolBitmapSize ((24 , 24 ))
1023
1027
self .wx_ids = {}
1024
1028
for text , tooltip_text , image_file , callback in self .toolitems :
1025
1029
if text is None :
@@ -1028,7 +1032,7 @@ def __init__(self, canvas, coordinates=True, *, style=wx.TB_BOTTOM):
1028
1032
self .wx_ids [text ] = (
1029
1033
self .AddTool (
1030
1034
- 1 ,
1031
- bitmap = self ._icon (f"{ image_file } .png " ),
1035
+ bitmap = self ._icon (f"{ image_file } .svg " ),
1032
1036
bmpDisabled = wx .NullBitmap ,
1033
1037
label = text , shortHelp = tooltip_text ,
1034
1038
kind = (wx .ITEM_CHECK if text in ["Pan" , "Zoom" ]
@@ -1054,9 +1058,7 @@ def _icon(name):
1054
1058
*name*, including the extension and relative to Matplotlib's "images"
1055
1059
data directory.
1056
1060
"""
1057
- pilimg = PIL .Image .open (cbook ._get_data_path ("images" , name ))
1058
- # ensure RGBA as wx BitMap expects RGBA format
1059
- image = np .array (pilimg .convert ("RGBA" ))
1061
+ svg = cbook ._get_data_path ("images" , name ).read_bytes ()
1060
1062
try :
1061
1063
dark = wx .SystemSettings .GetAppearance ().IsDark ()
1062
1064
except AttributeError : # wxpython < 4.1
@@ -1068,11 +1070,9 @@ def _icon(name):
1068
1070
fg_lum = (.299 * fg .red + .587 * fg .green + .114 * fg .blue ) / 255
1069
1071
dark = fg_lum - bg_lum > .2
1070
1072
if dark :
1071
- fg = wx .SystemSettings .GetColour (wx .SYS_COLOUR_WINDOWTEXT )
1072
- black_mask = (image [..., :3 ] == 0 ).all (axis = - 1 )
1073
- image [black_mask , :3 ] = (fg .Red (), fg .Green (), fg .Blue ())
1074
- return wx .Bitmap .FromBufferRGBA (
1075
- image .shape [1 ], image .shape [0 ], image .tobytes ())
1073
+ svg = svg .replace (b'fill:black;' , b'fill:white;' )
1074
+ toolbarIconSize = wx .ArtProvider ().GetDIPSizeHint (wx .ART_TOOLBAR )
1075
+ return wx .BitmapBundle .FromSVG (svg , toolbarIconSize )
1076
1076
1077
1077
def _update_buttons_checked (self ):
1078
1078
if "Pan" in self .wx_ids :
0 commit comments