Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e169aff

Browse filesBrowse files
authored
Merge pull request #8683 from anntzer/qt-subplottool
ENH: Simplify and improve Qt borders/spacing tool
2 parents eea8e4f + 56e9f1b commit e169aff
Copy full SHA for e169aff

File tree

Expand file treeCollapse file tree

3 files changed

+112
-317
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+112
-317
lines changed

‎lib/matplotlib/backends/backend_qt4.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_qt4.py
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from matplotlib.widgets import SubplotTool
2525

2626
from .qt_compat import QtCore, QtWidgets, _getSaveFileName, __version__
27-
from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool
2827

2928
from .backend_qt5 import (backend_version, SPECIAL_KEYS, SUPER, ALT, CTRL,
3029
SHIFT, MODIFIER_KEYS, fn_name, cursord,

‎lib/matplotlib/backends/backend_qt5.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backends/backend_qt5.py
+63-93Lines changed: 63 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from matplotlib._pylab_helpers import Gcf
2222
from matplotlib.figure import Figure
2323

24-
from matplotlib.widgets import SubplotTool
2524
import matplotlib.backends.qt_editor.figureoptions as figureoptions
2625

2726
from .qt_compat import (QtCore, QtGui, QtWidgets, _getSaveFileName,
@@ -778,101 +777,72 @@ def save_figure(self, *args):
778777
QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.NoButton)
779778

780779

781-
class SubplotToolQt(SubplotTool, UiSubplotTool):
780+
class SubplotToolQt(UiSubplotTool):
782781
def __init__(self, targetfig, parent):
783782
UiSubplotTool.__init__(self, None)
784783

785-
self.targetfig = targetfig
786-
self.parent = parent
787-
self.donebutton.clicked.connect(self.close)
788-
self.resetbutton.clicked.connect(self.reset)
789-
self.tightlayout.clicked.connect(self.functight)
790-
791-
# constraints
792-
self.sliderleft.valueChanged.connect(self.sliderright.setMinimum)
793-
self.sliderright.valueChanged.connect(self.sliderleft.setMaximum)
794-
self.sliderbottom.valueChanged.connect(self.slidertop.setMinimum)
795-
self.slidertop.valueChanged.connect(self.sliderbottom.setMaximum)
796-
797-
self.defaults = {}
798-
for attr in ('left', 'bottom', 'right', 'top', 'wspace', 'hspace', ):
799-
val = getattr(self.targetfig.subplotpars, attr)
800-
self.defaults[attr] = val
801-
slider = getattr(self, 'slider' + attr)
802-
txt = getattr(self, attr + 'value')
803-
slider.setMinimum(0)
804-
slider.setMaximum(1000)
805-
slider.setSingleStep(5)
806-
# do this before hooking up the callbacks
807-
slider.setSliderPosition(int(val * 1000))
808-
txt.setText("%.2f" % val)
809-
slider.valueChanged.connect(getattr(self, 'func' + attr))
810-
self._setSliderPositions()
811-
812-
def _setSliderPositions(self):
813-
for attr in ('left', 'bottom', 'right', 'top', 'wspace', 'hspace', ):
814-
slider = getattr(self, 'slider' + attr)
815-
slider.setSliderPosition(int(self.defaults[attr] * 1000))
816-
817-
def funcleft(self, val):
818-
if val == self.sliderright.value():
819-
val -= 1
820-
val /= 1000.
821-
self.targetfig.subplots_adjust(left=val)
822-
self.leftvalue.setText("%.2f" % val)
823-
if self.drawon:
824-
self.targetfig.canvas.draw_idle()
825-
826-
def funcright(self, val):
827-
if val == self.sliderleft.value():
828-
val += 1
829-
val /= 1000.
830-
self.targetfig.subplots_adjust(right=val)
831-
self.rightvalue.setText("%.2f" % val)
832-
if self.drawon:
833-
self.targetfig.canvas.draw_idle()
834-
835-
def funcbottom(self, val):
836-
if val == self.slidertop.value():
837-
val -= 1
838-
val /= 1000.
839-
self.targetfig.subplots_adjust(bottom=val)
840-
self.bottomvalue.setText("%.2f" % val)
841-
if self.drawon:
842-
self.targetfig.canvas.draw_idle()
843-
844-
def functop(self, val):
845-
if val == self.sliderbottom.value():
846-
val += 1
847-
val /= 1000.
848-
self.targetfig.subplots_adjust(top=val)
849-
self.topvalue.setText("%.2f" % val)
850-
if self.drawon:
851-
self.targetfig.canvas.draw_idle()
852-
853-
def funcwspace(self, val):
854-
val /= 1000.
855-
self.targetfig.subplots_adjust(wspace=val)
856-
self.wspacevalue.setText("%.2f" % val)
857-
if self.drawon:
858-
self.targetfig.canvas.draw_idle()
859-
860-
def funchspace(self, val):
861-
val /= 1000.
862-
self.targetfig.subplots_adjust(hspace=val)
863-
self.hspacevalue.setText("%.2f" % val)
864-
if self.drawon:
865-
self.targetfig.canvas.draw_idle()
866-
867-
def functight(self):
868-
self.targetfig.tight_layout()
869-
self._setSliderPositions()
870-
self.targetfig.canvas.draw_idle()
871-
872-
def reset(self):
873-
self.targetfig.subplots_adjust(**self.defaults)
874-
self._setSliderPositions()
875-
self.targetfig.canvas.draw_idle()
784+
self._figure = targetfig
785+
786+
for lower, higher in [("bottom", "top"), ("left", "right")]:
787+
self._widgets[lower].valueChanged.connect(
788+
lambda val: self._widgets[higher].setMinimum(val + .001))
789+
self._widgets[higher].valueChanged.connect(
790+
lambda val: self._widgets[lower].setMaximum(val - .001))
791+
792+
self._attrs = ["top", "bottom", "left", "right", "hspace", "wspace"]
793+
self._defaults = {attr: vars(self._figure.subplotpars)[attr]
794+
for attr in self._attrs}
795+
796+
# Set values after setting the range callbacks, but before setting up
797+
# the redraw callbacks.
798+
self._reset()
799+
800+
for attr in self._attrs:
801+
self._widgets[attr].valueChanged.connect(self._on_value_changed)
802+
for action, method in [("Export values", self._export_values),
803+
("Tight layout", self._tight_layout),
804+
("Reset", self._reset),
805+
("Close", self.close)]:
806+
self._widgets[action].clicked.connect(method)
807+
808+
def _export_values(self):
809+
# Explicitly round to 3 decimals (which is also the spinbox precision)
810+
# to avoid numbers of the form 0.100...001.
811+
dialog = QtWidgets.QDialog()
812+
layout = QtWidgets.QVBoxLayout()
813+
dialog.setLayout(layout)
814+
text = QtWidgets.QPlainTextEdit()
815+
text.setReadOnly(True)
816+
layout.addWidget(text)
817+
text.setPlainText(
818+
",\n".join("{}={:.3}".format(attr, self._widgets[attr].value())
819+
for attr in self._attrs))
820+
# Adjust the height of the text widget to fit the whole text, plus
821+
# some padding.
822+
size = text.maximumSize()
823+
size.setHeight(
824+
QtGui.QFontMetrics(text.document().defaultFont())
825+
.size(0, text.toPlainText()).height() + 20)
826+
text.setMaximumSize(size)
827+
dialog.exec_()
828+
829+
def _on_value_changed(self):
830+
self._figure.subplots_adjust(**{attr: self._widgets[attr].value()
831+
for attr in self._attrs})
832+
self._figure.canvas.draw_idle()
833+
834+
def _tight_layout(self):
835+
self._figure.tight_layout()
836+
for attr in self._attrs:
837+
widget = self._widgets[attr]
838+
widget.blockSignals(True)
839+
widget.setValue(vars(self._figure.subplotpars)[attr])
840+
widget.blockSignals(False)
841+
self._figure.canvas.draw_idle()
842+
843+
def _reset(self):
844+
for attr, value in self._defaults.items():
845+
self._widgets[attr].setValue(value)
876846

877847

878848
def error_msg_qt(msg, parent=None):

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.