21
21
from matplotlib ._pylab_helpers import Gcf
22
22
from matplotlib .figure import Figure
23
23
24
- from matplotlib .widgets import SubplotTool
25
24
import matplotlib .backends .qt_editor .figureoptions as figureoptions
26
25
27
26
from .qt_compat import (QtCore , QtGui , QtWidgets , _getSaveFileName ,
@@ -778,101 +777,72 @@ def save_figure(self, *args):
778
777
QtWidgets .QMessageBox .Ok , QtWidgets .QMessageBox .NoButton )
779
778
780
779
781
- class SubplotToolQt (SubplotTool , UiSubplotTool ):
780
+ class SubplotToolQt (UiSubplotTool ):
782
781
def __init__ (self , targetfig , parent ):
783
782
UiSubplotTool .__init__ (self , None )
784
783
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 )
876
846
877
847
878
848
def error_msg_qt (msg , parent = None ):
0 commit comments