Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2403,6 +2403,8 @@ def key_press_handler(event, canvas, toolbar=None):
else:
a.set_navigate(i==n)

class NonGuiException(Exception):
pass

class FigureManagerBase:
"""
Expand Down Expand Up @@ -2433,6 +2435,15 @@ def __init__(self, canvas, num):

"""

def show(self):
"""
For GUI backends, show the figure window and redraw.
For non-GUI backends, raise an exception to be caught
by :meth:`~matplotlib.figure.Figure.show`, for an
optional warning.
"""
raise NonGuiException()

def destroy(self):
pass

Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/backends/backend_fltkagg.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def handle(self, event):
self._key=special_key[ikey]
except:
self._key=None

# TODO: Handle ctrl, alt, super modifiers.
FigureCanvasBase.key_press_event(self._source, self._key)
return 1
Expand Down
9 changes: 3 additions & 6 deletions lib/matplotlib/backends/backend_gtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,14 @@ def _get_key(self, event):
key = chr(event.keyval)
else:
key = None

for key_mask, prefix in (
[gdk.MOD4_MASK, 'super'],
[gdk.MOD1_MASK, 'alt'],
[gdk.MOD1_MASK, 'alt'],
[gdk.CONTROL_MASK, 'ctrl'],):
if event.state & key_mask:
key = '{}+{}'.format(prefix, key)

return key

def configure_event(self, widget, event):
Expand Down Expand Up @@ -553,9 +553,6 @@ def __init__(self, canvas, num):

self.canvas.show()

# attach a show method to the figure for pylab ease of use
self.canvas.figure.show = lambda *args: self.window.show()

self.vbox.pack_start(self.canvas, True, True)

self.toolbar = self._get_toolbar(canvas)
Expand Down
5 changes: 1 addition & 4 deletions lib/matplotlib/backends/backend_gtk3.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,6 @@ def __init__(self, canvas, num):

self.canvas.show()

# attach a show method to the figure for pylab ease of use
self.canvas.figure.show = lambda *args: self.window.show()

self.vbox.pack_start(self.canvas, True, True, 0)

self.toolbar = self._get_toolbar(canvas)
Expand Down Expand Up @@ -564,7 +561,7 @@ def configure_subplots(self, button):


window = Gtk.Window()
try:
try:
window.set_icon_from_file(window_icon)
except (SystemExit, KeyboardInterrupt):
# re-raise exit type Exceptions
Expand Down
3 changes: 0 additions & 3 deletions lib/matplotlib/backends/backend_macosx.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,9 +376,6 @@ def notify_axes_change(fig):
if self.toolbar != None: self.toolbar.update()
self.canvas.figure.add_axobserver(notify_axes_change)

# This is ugly, but this is what tkagg and gtk are doing.
# It is needed to get ginput() working.
self.canvas.figure.show = lambda *args: self.show()
if matplotlib.is_interactive():
self.show()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note a subtle difference between the macosx backend and most others for the show. macosx backend uses self.show() instead of self.window.show(). I am also concerned about the note saying that this is needed to make ginput() work correctly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WeatherGod: No problem, as far as I can see. The backends that were using self.window.show also had methods self.show that were defined as self.window.show, so the difference between patching in self.window.show and self.show was zilch.

Ginput works fine on macosx after this PR.

Expand Down
5 changes: 1 addition & 4 deletions lib/matplotlib/backends/backend_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,6 @@ def __init__( self, canvas, num ):
if matplotlib.is_interactive():
self.window.show()

# attach a show method to the figure for pylab ease of use
self.canvas.figure.show = lambda *args: self.window.show()

def notify_axes_change( fig ):
# This will be called whenever the current axes is changed
if self.toolbar != None: self.toolbar.update()
Expand Down Expand Up @@ -330,7 +327,7 @@ def _init_toolbar( self ):
continue

fname = os.path.join(basedir, image_file + '.ppm')
image = qt.QPixmap()
image = qt.QPixmap()
image.load( fname )

button = qt.QPushButton( qt.QIconSet( image ), "", self )
Expand Down
3 changes: 0 additions & 3 deletions lib/matplotlib/backends/backend_qt4.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,6 @@ def __init__( self, canvas, num ):
if matplotlib.is_interactive():
self.window.show()

# attach a show method to the figure for pylab ease of use
self.canvas.figure.show = lambda *args: self.window.show()

def notify_axes_change( fig ):
# This will be called whenever the current axes is changed
if self.toolbar is not None:
Expand Down
43 changes: 20 additions & 23 deletions lib/matplotlib/backends/backend_tkagg.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def new_figure_manager_given_figure(num, figure):
"""
_focus = windowing.FocusManager()
window = Tk.Tk()

if Tk.TkVersion >= 8.5:
# put a mpl icon on the window rather than the default tk icon. Tkinter
# doesn't allow colour icons on linux systems, but tk >=8.5 has a iconphoto
Expand All @@ -101,7 +101,7 @@ def new_figure_manager_given_figure(num, figure):
except:
# log the failure, but carry on
verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])

canvas = FigureCanvasTkAgg(figure, master=window)
figManager = FigureManagerTkAgg(canvas, num, window)
if matplotlib.is_interactive():
Expand Down Expand Up @@ -199,7 +199,7 @@ class FigureCanvasTkAgg(FigureCanvasAgg):
65439 : 'dec',
65421 : 'enter',
}

_keycode_lookup = {
262145: 'control',
524320: 'alt',
Expand Down Expand Up @@ -254,7 +254,7 @@ def filter_destroy(evt):

self._master = master
self._tkcanvas.focus_set()

def resize(self, event):
width, height = event.width, event.height
if self._resize_callback is not None:
Expand Down Expand Up @@ -443,31 +443,31 @@ def _get_key(self, event):
key = chr(val)
else:
key = None
# add modifier keys to the key string. Bit details originate from

# add modifier keys to the key string. Bit details originate from
# http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
# BIT_SHIFT = 0x001; BIT_CAPSLOCK = 0x002; BIT_CONTROL = 0x004;
# BIT_LEFT_ALT = 0x008; BIT_NUMLOCK = 0x010; BIT_RIGHT_ALT = 0x080;
# BIT_SHIFT = 0x001; BIT_CAPSLOCK = 0x002; BIT_CONTROL = 0x004;
# BIT_LEFT_ALT = 0x008; BIT_NUMLOCK = 0x010; BIT_RIGHT_ALT = 0x080;
# BIT_MB_1 = 0x100; BIT_MB_2 = 0x200; BIT_MB_3 = 0x400;
# In general, the modifier key is excluded from the modifier flag,
# however this is not the case on "darwin", so double check that
# In general, the modifier key is excluded from the modifier flag,
# however this is not the case on "darwin", so double check that
# we aren't adding repeat modifier flags to a modifier key.
modifiers = [(6, 'super', 'super'),
(3, 'alt', 'alt'),
modifiers = [(6, 'super', 'super'),
(3, 'alt', 'alt'),
(2, 'ctrl', 'control'),
]
if sys.platform == 'darwin':
modifiers = [(3, 'super', 'super'),
(4, 'alt', 'alt'),
modifiers = [(3, 'super', 'super'),
(4, 'alt', 'alt'),
(2, 'ctrl', 'control'),
]

if key is not None:
# note, shift is not added to the keys as this is already accounted for
for bitmask, prefix, key_name in modifiers:
if event.state & (1 << bitmask) and key_name not in key:
if event.state & (1 << bitmask) and key_name not in key:
key = '{}+{}'.format(prefix, key)

return key

def key_press(self, event):
Expand Down Expand Up @@ -542,9 +542,6 @@ def notify_axes_change(fig):
if self.toolbar != None: self.toolbar.update()
self.canvas.figure.add_axobserver(notify_axes_change)

# attach a show method to the figure for pylab ease of use
self.canvas.figure.show = lambda *args: self.show()

def resize(self, width, height=None):
# before 09-12-22, the resize method takes a single *event*
# parameter. On the other hand, the resize method of other
Expand Down Expand Up @@ -852,14 +849,14 @@ def _init_toolbar(self):

for text, tooltip_text, image_file, callback in self.toolitems:
if text is None:
# spacer, unhandled in Tk
# spacer, unhandled in Tk
pass
else:
button = self._Button(text=text, file=image_file,
command=getattr(self, callback))
if tooltip_text is not None:
ToolTip.createToolTip(button, tooltip_text)

self.message = Tk.StringVar(master=self)
self._message_label = Tk.Label(master=self, textvariable=self.message)
self._message_label.pack(side=Tk.RIGHT)
Expand Down Expand Up @@ -954,7 +951,7 @@ def leave(event):
toolTip.hidetip()
widget.bind('<Enter>', enter)
widget.bind('<Leave>', leave)

def __init__(self, widget):
self.widget = widget
self.tipwindow = None
Expand Down
18 changes: 6 additions & 12 deletions lib/matplotlib/backends/backend_wx.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,8 @@ def Copy_to_Clipboard(self, event=None):
"copy bitmap of canvas to system clipboard"
bmp_obj = wx.BitmapDataObject()
bmp_obj.SetBitmap(self.bitmap)
if not wx.TheClipboard.IsOpened():

if not wx.TheClipboard.IsOpened():
open_success = wx.TheClipboard.Open()
if open_success:
wx.TheClipboard.SetData(bmp_obj)
Expand Down Expand Up @@ -1251,7 +1251,7 @@ def _get_key(self, evt):
key = None

for meth, prefix in (
[evt.AltDown, 'alt'],
[evt.AltDown, 'alt'],
[evt.ControlDown, 'ctrl'], ):
if meth():
key = '{}+{}'.format(prefix, key)
Expand Down Expand Up @@ -1421,7 +1421,7 @@ def _create_wx_app():
# retain a reference to the app object so it does not get garbage
# collected and cause segmentation faults
_create_wx_app.theWxApp = wxapp


def draw_if_interactive():
"""
Expand Down Expand Up @@ -1521,7 +1521,7 @@ def __init__(self, num, fig):
self.Fit()

self.canvas.SetMinSize((2, 2))

# give the window a matplotlib icon rather than the stock one.
# This is not currently working on Linux and is untested elsewhere.
#icon_path = os.path.join(matplotlib.rcParams['datapath'],
Expand Down Expand Up @@ -1603,12 +1603,6 @@ def notify_axes_change(fig):
if self.tb != None: self.tb.update()
self.canvas.figure.add_axobserver(notify_axes_change)

def showfig(*args):
frame.Show()

# attach a show method to the figure
self.canvas.figure.show = showfig

def show(self):
self.frame.Show()

Expand Down Expand Up @@ -1882,7 +1876,7 @@ def save_figure(self, *args):
os.path.join(dirname, filename), format=format)
except Exception as e:
error_msg_wx(str(e))

def set_cursor(self, cursor):
cursor =wx.StockCursor(cursord[cursor])
self.canvas.SetCursor( cursor )
Expand Down
26 changes: 23 additions & 3 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from matplotlib.text import Text, _process_text_args
from matplotlib.transforms import (Affine2D, Bbox, BboxTransformTo,
TransformedBbox)

from matplotlib.backend_bases import NonGuiException

docstring.interpd.update(projection_names = get_projection_names())

Expand Down Expand Up @@ -338,6 +338,26 @@ def _setup_canvas(self):
backend_mod = mbackends.pylab_setup()[0]
return backend_mod.FigureCanvas(self)

def show(self, warn=True):
"""
If using a GUI backend, display the figure window.

For non-GUI backends, this does nothing, in which case
a warning will be issued if *warn* is True.
"""
manager = getattr(self.canvas, 'manager')
if manager is not None:
try:
manager.show()
return
except NonGuiException:
pass
if warn:
import warnings
warnings.warn(
"matplotlib is currently using a non-GUI backend, "
"so cannot show the figure")

def _get_axes(self):
return self._axstack.as_list()

Expand Down Expand Up @@ -1188,10 +1208,10 @@ def __getstate__(self):
# and re-attached to another.
for attr_to_pop in ('_axobservers', 'show', 'canvas', '_cachedRenderer') :
state.pop(attr_to_pop, None)

# add version information to the state
state['__mpl_version__'] = _mpl_version

# check to see if the figure has a manager and whether it is registered
# with pyplot
if getattr(self.canvas, 'manager', None) is not None:
Expand Down