Skip to content

Bind subplot_tool more closely to target figure. #21681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 20, 2021
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
19 changes: 17 additions & 2 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -3258,9 +3258,24 @@ def _update_view(self):
self.canvas.draw_idle()

def configure_subplots(self, *args):
if hasattr(self, "subplot_tool"):
self.subplot_tool.figure.canvas.manager.show()
return
plt = _safe_pyplot_import()
self.subplot_tool = plt.subplot_tool(self.canvas.figure)
self.subplot_tool.figure.canvas.manager.show()
with mpl.rc_context({"toolbar": "none"}): # No navbar for the toolfig.
# Use new_figure_manager() instead of figure() so that the figure
# doesn't get registered with pyplot.
manager = plt.new_figure_manager(-1, (6, 3))
manager.set_window_title("Subplot configuration tool")
tool_fig = manager.canvas.figure
tool_fig.subplots_adjust(top=0.9)
self.subplot_tool = widgets.SubplotTool(self.canvas.figure, tool_fig)
tool_fig.canvas.mpl_connect(
"close_event", lambda e: delattr(self, "subplot_tool"))
self.canvas.mpl_connect(
"close_event", lambda e: manager.destroy())
manager.show()
return self.subplot_tool

def save_figure(self, *args):
"""Save the current figure."""
Expand Down
23 changes: 16 additions & 7 deletions lib/matplotlib/backends/backend_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,11 +750,14 @@ def remove_rubberband(self):
self.canvas.drawRectangle(None)

def configure_subplots(self):
image = str(cbook._get_data_path('images/matplotlib.png'))
self._subplot_dialog = SubplotToolQt(
self.canvas.figure, self.canvas.parent())
self._subplot_dialog.setWindowIcon(QtGui.QIcon(image))
if self._subplot_dialog is None:
self._subplot_dialog = SubplotToolQt(
self.canvas.figure, self.canvas.parent())
self.canvas.mpl_connect(
"close_event", lambda e: self._subplot_dialog.reject())
self._subplot_dialog.update_from_current_subplotpars()
self._subplot_dialog.show()
return self._subplot_dialog

def save_figure(self, *args):
filetypes = self.canvas.get_supported_filetypes_grouped()
Expand Down Expand Up @@ -799,6 +802,8 @@ def set_history_buttons(self):
class SubplotToolQt(QtWidgets.QDialog):
def __init__(self, targetfig, parent):
super().__init__()
self.setWindowIcon(QtGui.QIcon(
str(cbook._get_data_path("images/matplotlib.png"))))
self.setObjectName("SubplotTool")
self._spinboxes = {}
main_layout = QtWidgets.QHBoxLayout()
Expand All @@ -819,7 +824,6 @@ def __init__(self, targetfig, parent):
inner = QtWidgets.QFormLayout(box)
for name in spinboxes:
self._spinboxes[name] = spinbox = QtWidgets.QDoubleSpinBox()
spinbox.setValue(getattr(targetfig.subplotpars, name))
spinbox.setRange(0, 1)
spinbox.setDecimals(3)
spinbox.setSingleStep(0.005)
Expand All @@ -836,9 +840,14 @@ def __init__(self, targetfig, parent):
if name == "Close":
button.setFocus()
self._figure = targetfig
self._defaults = {spinbox: vars(self._figure.subplotpars)[attr]
for attr, spinbox in self._spinboxes.items()}
self._defaults = {}
self._export_values_dialog = None
self.update_from_current_subplotpars()

def update_from_current_subplotpars(self):
self._defaults = {spinbox: getattr(self._figure.subplotpars, name)
for name, spinbox in self._spinboxes.items()}
self._reset() # Set spinbox current values without triggering signals.

def _export_values(self):
# Explicitly round to 3 decimals (which is also the spinbox precision)
Expand Down
24 changes: 12 additions & 12 deletions lib/matplotlib/pyplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
from matplotlib.lines import Line2D
from matplotlib.text import Text, Annotation
from matplotlib.patches import Polygon, Rectangle, Circle, Arrow
from matplotlib.widgets import SubplotTool, Button, Slider, Widget
from matplotlib.widgets import Button, Slider, Widget

from .ticker import (
TickHelper, Formatter, FixedFormatter, NullFormatter, FuncFormatter,
Expand Down Expand Up @@ -1627,20 +1627,20 @@ def subplot_tool(targetfig=None):
"""
Launch a subplot tool window for a figure.

A `matplotlib.widgets.SubplotTool` instance is returned. You must maintain
a reference to the instance to keep the associated callbacks alive.
Returns
-------
`matplotlib.widgets.SubplotTool`
"""
if targetfig is None:
targetfig = gcf()
with rc_context({"toolbar": "none"}): # No navbar for the toolfig.
# Use new_figure_manager() instead of figure() so that the figure
# doesn't get registered with pyplot.
manager = new_figure_manager(-1, (6, 3))
manager.set_window_title("Subplot configuration tool")
tool_fig = manager.canvas.figure
tool_fig.subplots_adjust(top=0.9)
manager.show()
return SubplotTool(targetfig, tool_fig)
tb = targetfig.canvas.manager.toolbar
if hasattr(tb, "configure_subplots"): # toolbar2
return tb.configure_subplots()
elif hasattr(tb, "trigger_tool"): # toolmanager
return tb.trigger_tool("subplots")
else:
raise ValueError("subplot_tool can only be launched for figures with "
"an associated toolbar")


def box(on=None):
Expand Down