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

Skip to content

Commit f4d742f

Browse files
committed
backend_ps cleanup.
Dedupe some code between backend_ps and backend_bases (the edgecolor and facecolor handling -- see changelog), as well as between the non-tex and tex cases (by formatting the header metadata ("dsc_comments") earlier). Also simplify a bit papersize handling in usetex case.
1 parent 25b80c3 commit f4d742f

File tree

2 files changed

+54
-105
lines changed

2 files changed

+54
-105
lines changed

doc/api/next_api_changes/behaviour.rst

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,15 @@ deprecation warning.
100100

101101
Previously setting the *ecolor* would turn off automatic color cycling for the plot, leading to the
102102
the lines and markers defaulting to whatever the first color in the color cycle was in the case of
103-
multiple plot calls.
103+
multiple plot calls.
104+
105+
`.FigureCanvasPS.print_ps` and `.FigureCanvasPS.print_eps` no longer apply edgecolor and facecolor
106+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
107+
108+
These methods now assume that the figure edge and facecolor have been correctly
109+
applied by `.FigureCanvasBase.print_figure`, as they are normally called
110+
through it.
111+
112+
This behavior is consistent with other figure saving methods
113+
(`.FigureCanvasAgg.print_png`, `.FigureCanvasPdf.print_pdf`,
114+
`.FigureCanvasSVG.print_svg`).

lib/matplotlib/backends/backend_ps.py

Lines changed: 42 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -764,10 +764,29 @@ def print_ps(self, outfile, *args, **kwargs):
764764
def print_eps(self, outfile, *args, **kwargs):
765765
return self._print_ps(outfile, 'eps', *args, **kwargs)
766766

767-
def _print_ps(self, outfile, format, *args,
768-
papertype=None, dpi=72, facecolor='w', edgecolor='w',
769-
orientation='portrait',
770-
**kwargs):
767+
def _print_ps(
768+
self, outfile, format, *args,
769+
dpi=72, metadata=None, papertype=None, orientation='portrait',
770+
**kwargs):
771+
772+
self.figure.set_dpi(72) # Override the dpi kwarg
773+
774+
dsc_comments = {}
775+
if isinstance(outfile, (str, os.PathLike)):
776+
dsc_comments["Title"] = \
777+
os.fspath(outfile).encode("ascii", "replace").decode("ascii")
778+
dsc_comments["Creator"] = (metadata or {}).get(
779+
"Creator",
780+
f"matplotlib version {mpl.__version__}, http://matplotlib.org/")
781+
source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
782+
dsc_comments["CreationDate"] = (
783+
datetime.datetime.utcfromtimestamp(
784+
int(source_date_epoch)).strftime("%a %b %d %H:%M:%S %Y")
785+
if source_date_epoch
786+
else time.ctime())
787+
dsc_comments = "\n".join(
788+
f"%%{k}: {v}" for k, v in dsc_comments.items())
789+
771790
if papertype is None:
772791
papertype = mpl.rcParams['ps.papersize']
773792
papertype = papertype.lower()
@@ -776,42 +795,29 @@ def _print_ps(self, outfile, format, *args,
776795
orientation = cbook._check_getitem(
777796
_Orientation, orientation=orientation.lower())
778797

779-
self.figure.set_dpi(72) # Override the dpi kwarg
780-
781798
printer = (self._print_figure_tex
782799
if mpl.rcParams['text.usetex'] else
783800
self._print_figure)
784-
printer(outfile, format, dpi, facecolor, edgecolor,
785-
orientation, papertype, **kwargs)
801+
printer(outfile, format, dpi=dpi, dsc_comments=dsc_comments,
802+
orientation=orientation, papertype=papertype, **kwargs)
786803

787804
@cbook._delete_parameter("3.2", "dryrun")
788805
def _print_figure(
789-
self, outfile, format, dpi, facecolor, edgecolor,
790-
orientation, papertype, *,
791-
metadata=None, dryrun=False, bbox_inches_restore=None, **kwargs):
806+
self, outfile, format, *,
807+
dpi, dsc_comments, orientation, papertype,
808+
dryrun=False, bbox_inches_restore=None, **kwargs):
792809
"""
793-
Render the figure to hardcopy. Set the figure patch face and
794-
edge colors. This is useful because some of the GUIs have a
795-
gray figure face color background and you'll probably want to
796-
override this on hardcopy
797-
798-
If outfile is a string, it is interpreted as a file name.
799-
If the extension matches .ep* write encapsulated postscript,
800-
otherwise write a stand-alone PostScript file.
801-
802-
If outfile is a file object, a stand-alone PostScript file is
803-
written into this file object.
810+
Render the figure to a filesystem path or a file-like object.
804811
805-
metadata must be a dictionary. Currently, only the value for
806-
the key 'Creator' is used.
812+
Parameters are as for `.print_figure`, except that *dsc_comments* is a
813+
all string containing Document Structuring Convention comments,
814+
generated from the *metadata* parameter to `.print_figure`.
807815
"""
808816
is_eps = format == 'eps'
809817
if isinstance(outfile, (str, os.PathLike)):
810-
outfile = title = os.fspath(outfile)
811-
title = title.encode("ascii", "replace").decode("ascii")
818+
outfile = os.fspath(outfile)
812819
passed_in_file_object = False
813820
elif is_writable_file_like(outfile):
814-
title = None
815821
passed_in_file_object = True
816822
else:
817823
raise ValueError("outfile must be a path or a file-like object")
@@ -848,12 +854,6 @@ def _print_figure(
848854
rotation = 90
849855
bbox = (llx, lly, urx, ury)
850856

851-
# generate PostScript code for the figure and store it in a string
852-
origfacecolor = self.figure.get_facecolor()
853-
origedgecolor = self.figure.get_edgecolor()
854-
self.figure.set_facecolor(facecolor)
855-
self.figure.set_edgecolor(edgecolor)
856-
857857
if dryrun:
858858
class NullWriter:
859859
def write(self, *args, **kwargs):
@@ -874,16 +874,6 @@ def write(self, *args, **kwargs):
874874
if dryrun: # return immediately if dryrun (tightbbox=True)
875875
return
876876

877-
self.figure.set_facecolor(origfacecolor)
878-
self.figure.set_edgecolor(origedgecolor)
879-
880-
# check for custom metadata
881-
if metadata is not None and 'Creator' in metadata:
882-
creator_str = metadata['Creator']
883-
else:
884-
creator_str = \
885-
f"matplotlib version {mpl.__version__}, http://matplotlib.org/"
886-
887877
def print_figure_impl(fh):
888878
# write the PostScript headers
889879
if is_eps:
@@ -893,18 +883,7 @@ def print_figure_impl(fh):
893883
f"%%DocumentPaperSizes: {papertype}\n"
894884
f"%%Pages: 1\n",
895885
end="", file=fh)
896-
if title:
897-
print("%%Title: " + title, file=fh)
898-
# get source date from SOURCE_DATE_EPOCH, if set
899-
# See https://reproducible-builds.org/specs/source-date-epoch/
900-
source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
901-
if source_date_epoch:
902-
source_date = datetime.datetime.utcfromtimestamp(
903-
int(source_date_epoch)).strftime("%a %b %d %H:%M:%S %Y")
904-
else:
905-
source_date = time.ctime()
906-
print(f"%%Creator: {creator_str}\n"
907-
f"%%CreationDate: {source_date}\n"
886+
print(f"{dsc_comments}\n"
908887
f"%%Orientation: {orientation.name}\n"
909888
f"%%BoundingBox: {bbox[0]} {bbox[1]} {bbox[2]} {bbox[3]}\n"
910889
f"%%EndComments\n",
@@ -1006,28 +985,18 @@ def print_figure_impl(fh):
1006985

1007986
@cbook._delete_parameter("3.2", "dryrun")
1008987
def _print_figure_tex(
1009-
self, outfile, format, dpi, facecolor, edgecolor,
1010-
orientation, papertype, *,
1011-
metadata=None, dryrun=False, bbox_inches_restore=None, **kwargs):
988+
self, outfile, format, *,
989+
dpi, dsc_comments, orientation, papertype,
990+
dryrun=False, bbox_inches_restore=None, **kwargs):
1012991
"""
1013-
If text.usetex is True in rc, a temporary pair of tex/eps files
992+
If :rc:`text.usetex` is True, a temporary pair of tex/eps files
1014993
are created to allow tex to manage the text layout via the PSFrags
1015994
package. These files are processed to yield the final ps or eps file.
1016995
1017-
metadata must be a dictionary. Currently, only the value for
1018-
the key 'Creator' is used.
996+
The rest of the behavior is as for `._print_figure`.
1019997
"""
1020998
is_eps = format == 'eps'
1021-
if is_writable_file_like(outfile):
1022-
title = None
1023-
else:
1024-
try:
1025-
title = os.fspath(outfile)
1026-
except TypeError:
1027-
raise ValueError(
1028-
"outfile must be a path or a file-like object")
1029999

1030-
self.figure.dpi = 72 # ignore the dpi kwarg
10311000
width, height = self.figure.get_size_inches()
10321001
xo = 0
10331002
yo = 0
@@ -1039,12 +1008,6 @@ def _print_figure_tex(
10391008
ury = lly + h
10401009
bbox = (llx, lly, urx, ury)
10411010

1042-
# generate PostScript code for the figure and store it in a string
1043-
origfacecolor = self.figure.get_facecolor()
1044-
origedgecolor = self.figure.get_edgecolor()
1045-
self.figure.set_facecolor(facecolor)
1046-
self.figure.set_edgecolor(edgecolor)
1047-
10481011
if dryrun:
10491012
class NullWriter:
10501013
def write(self, *args, **kwargs):
@@ -1065,35 +1028,13 @@ def write(self, *args, **kwargs):
10651028
if dryrun: # return immediately if dryrun (tightbbox=True)
10661029
return
10671030

1068-
self.figure.set_facecolor(origfacecolor)
1069-
self.figure.set_edgecolor(origedgecolor)
1070-
1071-
# check for custom metadata
1072-
if metadata is not None and 'Creator' in metadata:
1073-
creator_str = metadata['Creator']
1074-
else:
1075-
creator_str = \
1076-
f"matplotlib version {mpl.__version__}, http://matplotlib.org/"
1077-
10781031
# write to a temp file, we'll move it to outfile when done
1079-
10801032
with TemporaryDirectory() as tmpdir:
10811033
tmpfile = os.path.join(tmpdir, "tmp.ps")
1082-
# get source date from SOURCE_DATE_EPOCH, if set
1083-
# See https://reproducible-builds.org/specs/source-date-epoch/
1084-
source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
1085-
if source_date_epoch:
1086-
source_date = datetime.datetime.utcfromtimestamp(
1087-
int(source_date_epoch)).strftime("%a %b %d %H:%M:%S %Y")
1088-
else:
1089-
source_date = time.ctime()
10901034
pathlib.Path(tmpfile).write_text(
10911035
f"""\
10921036
%!PS-Adobe-3.0 EPSF-3.0
1093-
{f'''%%Title: {title}
1094-
''' if title else ""}\
1095-
%%Creator: {creator_str}
1096-
%%CreationDate: {source_date}
1037+
{dsc_comments}
10971038
%%BoundingBox: {bbox[0]} {bbox[1]} {bbox[2]} {bbox[3]}
10981039
%%EndComments
10991040
%%BeginProlog
@@ -1122,12 +1063,9 @@ def write(self, *args, **kwargs):
11221063
paper_width, paper_height = orientation.swap_if_landscape(
11231064
self.figure.get_size_inches())
11241065
else:
1125-
temp_papertype = _get_papertype(width, height)
11261066
if papertype == 'auto':
1127-
papertype = temp_papertype
1128-
paper_width, paper_height = papersize[temp_papertype]
1129-
else:
1130-
paper_width, paper_height = papersize[papertype]
1067+
papertype = _get_papertype(width, height)
1068+
paper_width, paper_height = papersize[papertype]
11311069

11321070
texmanager = ps_renderer.get_texmanager()
11331071
font_preamble = texmanager.get_font_preamble()

0 commit comments

Comments
 (0)