Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3652e4a

Browse files
committed
Interactive setting of savefig rcParams (Qt only).
An additional window pops after selecting the filename to allow setting of savefig-related rcParams. For simplicity and consistency, the "ps.usedistiller" rcParam is now normalized to `None` when not set.
1 parent ab98852 commit 3652e4a

File tree

3 files changed

+110
-19
lines changed

3 files changed

+110
-19
lines changed

lib/matplotlib/backends/backend_qt5.py

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727

2828
from .qt_compat import (QtCore, QtGui, QtWidgets, _getSaveFileName,
2929
__version__, is_pyqt5)
30-
from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool
30+
from .qt_editor import formlayout
31+
from .qt_editor.formsubplottool import UiSubplotTool
3132

3233
backend_version = __version__
3334

@@ -725,19 +726,19 @@ def save_figure(self, *args):
725726
startpath = matplotlib.rcParams.get('savefig.directory', '')
726727
startpath = os.path.expanduser(startpath)
727728
start = os.path.join(startpath, self.canvas.get_default_filename())
729+
728730
filters = []
729-
selectedFilter = None
731+
selected_filter = None
730732
for name, exts in sorted_filetypes:
731-
exts_list = " ".join(['*.%s' % ext for ext in exts])
732-
filter = '%s (%s)' % (name, exts_list)
733+
filters.append(
734+
'{} ({})'.format(name, ' '.join(map('*.{}'.format, exts))))
733735
if default_filetype in exts:
734-
selectedFilter = filter
735-
filters.append(filter)
736+
selected_filter = filters[-1]
736737
filters = ';;'.join(filters)
737738

738-
fname, filter = _getSaveFileName(self.parent,
739-
"Choose a filename to save to",
740-
start, filters, selectedFilter)
739+
fname, selected_filter = _getSaveFileName(
740+
self.parent, "Choose a filename to save to",
741+
start, filters, selected_filter)
741742
if fname:
742743
if startpath == '':
743744
# explicitly missing key or empty str signals to use cwd
@@ -746,6 +747,25 @@ def save_figure(self, *args):
746747
# save dir for next time
747748
savefig_dir = os.path.dirname(six.text_type(fname))
748749
matplotlib.rcParams['savefig.directory'] = savefig_dir
750+
options = _default_savefig_options
751+
try:
752+
options = (options
753+
+ [None]
754+
+ _extra_savefig_options[
755+
os.path.splitext(fname)[1].lower()])
756+
except KeyError:
757+
pass
758+
fedit_arg = []
759+
for option in options:
760+
if option is None:
761+
fedit_arg.append((None, None))
762+
else:
763+
fedit_arg.append(option.make_fedit_entry())
764+
fedit_res = formlayout.fedit(fedit_arg, "Options")
765+
if not fedit_res:
766+
return
767+
for option, res in zip(filter(None, options), fedit_res):
768+
option.setter(res)
749769
try:
750770
self.canvas.print_figure(six.text_type(fname))
751771
except Exception as e:
@@ -754,6 +774,79 @@ def save_figure(self, *args):
754774
QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.NoButton)
755775

756776

777+
class _Option(object):
778+
779+
def __init__(self, name, rc_key=None, getter=None, setter=None):
780+
if rc_key and not (getter or setter):
781+
def make_fedit_entry():
782+
return (name, matplotlib.rcParams[rc_key])
783+
784+
def setter(val):
785+
matplotlib.rcParams[rc_key] = val
786+
787+
elif getter and setter and not rc_key:
788+
def make_fedit_entry():
789+
return (name, getter())
790+
791+
else:
792+
raise ValueError("Invalid entry")
793+
794+
self.name = name
795+
self.make_fedit_entry = make_fedit_entry
796+
self.setter = setter
797+
798+
799+
_default_savefig_options = [
800+
_Option("DPI", "savefig.dpi"),
801+
_Option("Face color", "savefig.facecolor"),
802+
_Option("Edge color", "savefig.edgecolor"),
803+
_Option("Tight bounding box",
804+
getter=lambda: matplotlib.rcParams["savefig.bbox"] == "tight",
805+
setter=lambda val: matplotlib.rcParams.__setitem__(
806+
"savefig.bbox", "tight" if val else "standard")),
807+
_Option("Tight bounding box padding", "savefig.pad_inches"),
808+
_Option("Transparent background", "savefig.transparent")]
809+
810+
811+
_extra_savefig_options = {
812+
".jpg": [
813+
_Option("JPEG quality", "savefig.jpeg_quality")],
814+
".jpeg": [
815+
_Option("JPEG quality", "savefig.jpeg_quality")],
816+
".pdf": [
817+
_Option("PDF compression", "pdf.compression"),
818+
_Option("PDF font type",
819+
getter=lambda:
820+
[str(matplotlib.rcParams["pdf.fonttype"]),
821+
"3", "42"],
822+
setter=lambda val:
823+
matplotlib.rcParams.__setitem__("pdf.fonttype", val))],
824+
".ps": [
825+
_Option("PS paper size",
826+
getter=lambda:
827+
[matplotlib.rcParams["ps.papersize"]]
828+
+ ["auto", "letter", "legal", "ledger"]
829+
+ ["A{}".format(i) for i in range(11)]
830+
+ ["B{}".format(i) for i in range(11)],
831+
setter=lambda val:
832+
matplotlib.rcParams.__setitem__("ps.papersize", val)),
833+
_Option("PS use AFM font", "ps.useafm"),
834+
_Option("PS distiller",
835+
getter=lambda:
836+
[str(matplotlib.rcParams["ps.usedistiller"])]
837+
+ ["None", "ghostscript", "xpdf"],
838+
setter=lambda val:
839+
matplotlib.rcParams.__setitem__("ps.usedistiller", val)),
840+
_Option("PS distiller resolution", "ps.distiller.res"),
841+
_Option("PS font type",
842+
getter=lambda:
843+
[str(matplotlib.rcParams["ps.fonttype"]),
844+
"3", "42"],
845+
setter=lambda val:
846+
matplotlib.rcParams.__setitem__("ps.fonttype", val))]
847+
}
848+
849+
757850
class SubplotToolQt(SubplotTool, UiSubplotTool):
758851
def __init__(self, targetfig, parent):
759852
UiSubplotTool.__init__(self, None)

lib/matplotlib/rcsetup.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -504,10 +504,8 @@ def update_savefig_format(value):
504504
def validate_ps_distiller(s):
505505
if isinstance(s, six.string_types):
506506
s = s.lower()
507-
if s in ('none', None):
507+
if s in ('none', None, 'false', False):
508508
return None
509-
elif s in ('false', False):
510-
return False
511509
elif s in ('ghostscript', 'xpdf'):
512510
return s
513511
else:
@@ -1269,7 +1267,7 @@ def validate_animation_writer_path(p):
12691267
'ps.papersize': ['letter', validate_ps_papersize],
12701268
'ps.useafm': [False, validate_bool], # Set PYTHONINSPECT
12711269
# use ghostscript or xpdf to distill ps output
1272-
'ps.usedistiller': [False, validate_ps_distiller],
1270+
'ps.usedistiller': [None, validate_ps_distiller],
12731271
'ps.distiller.res': [6000, validate_int], # dpi
12741272
'ps.fonttype': [3, validate_fonttype], # 3 (Type3) or 42 (Truetype)
12751273
# compression level from 0 to 9; 0 to disable

matplotlibrc.template

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -538,12 +538,12 @@ backend : $TEMPLATE_BACKEND
538538
# ps backend params
539539
#ps.papersize : letter # auto, letter, legal, ledger, A0-A10, B0-B10
540540
#ps.useafm : False # use of afm fonts, results in small files
541-
#ps.usedistiller : False # can be: None, ghostscript or xpdf
542-
# Experimental: may produce smaller files.
543-
# xpdf intended for production of publication quality files,
544-
# but requires ghostscript, xpdf and ps2eps
545-
#ps.distiller.res : 6000 # dpi
546-
#ps.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType)
541+
#ps.usedistiller : None # can be: None, ghostscript or xpdf
542+
# Experimental: may produce smaller files.
543+
# xpdf intended for production of publication quality files,
544+
# but requires ghostscript, xpdf and ps2eps
545+
#ps.distiller.res : 6000 # dpi
546+
#ps.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType)
547547

548548
# pdf backend params
549549
#pdf.compression : 6 # integer from 0 to 9

0 commit comments

Comments
 (0)