Пример #1
0
        def print_figure_impl(fh):
            # write the PostScript headers
            if is_eps:
                print("%!PS-Adobe-3.0 EPSF-3.0", file=fh)
            else:
                print(f"%!PS-Adobe-3.0\n"
                      f"%%DocumentPaperSizes: {papertype}\n"
                      f"%%Pages: 1\n",
                      end="", file=fh)
            print(f"{dsc_comments}\n"
                  f"%%Orientation: {orientation.name}\n"
                  f"%%BoundingBox: {bbox[0]} {bbox[1]} {bbox[2]} {bbox[3]}\n"
                  f"%%EndComments\n",
                  end="", file=fh)

            Ndict = len(psDefs)
            print("%%BeginProlog", file=fh)
            if not mpl.rcParams['ps.useafm']:
                Ndict += len(ps_renderer._character_tracker.used)
            print("/mpldict %d dict def" % Ndict, file=fh)
            print("mpldict begin", file=fh)
            print("\n".join(psDefs), file=fh)
            if not mpl.rcParams['ps.useafm']:
                for font_path, chars \
                        in ps_renderer._character_tracker.used.items():
                    if not chars:
                        continue
                    font = get_font(font_path)
                    glyph_ids = [font.get_char_index(c) for c in chars]
                    fonttype = mpl.rcParams['ps.fonttype']
                    # Can't use more than 255 chars from a single Type 3 font.
                    if len(glyph_ids) > 255:
                        fonttype = 42
                    # The ttf to ps (subsetting) support doesn't work for
                    # OpenType fonts that are Postscript inside (like the STIX
                    # fonts).  This will simply turn that off to avoid errors.
                    if is_opentype_cff_font(font_path):
                        raise RuntimeError(
                            "OpenType CFF fonts can not be saved using "
                            "the internal Postscript backend at this "
                            "time; consider using the Cairo backend")
                    fh.flush()
                    try:
                        convert_ttf_to_ps(os.fsencode(font_path),
                                          fh, fonttype, glyph_ids)
                    except RuntimeError:
                        _log.warning("The PostScript backend does not "
                                     "currently support the selected font.")
                        raise
            print("end", file=fh)
            print("%%EndProlog", file=fh)

            if not is_eps:
                print("%%Page: 1 1", file=fh)
            print("mpldict begin", file=fh)

            print("%s translate" % _nums_to_str(xo, yo), file=fh)
            if rotation:
                print("%d rotate" % rotation, file=fh)
            print("%s clipbox" % _nums_to_str(width*72, height*72, 0, 0),
                  file=fh)

            # write the figure
            content = self._pswriter.getvalue()
            if not isinstance(content, str):
                content = content.decode('ascii')
            print(content, file=fh)

            # write the trailer
            print("end", file=fh)
            print("showpage", file=fh)
            if not is_eps:
                print("%%EOF", file=fh)
            fh.flush()
Пример #2
0
    def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w',
                      orientation='portrait', isLandscape=False, papertype=None):
        """
        Render the figure to hardcopy.  Set the figure patch face and
        edge colors.  This is useful because some of the GUIs have a
        gray figure face color background and you'll probably want to
        override this on hardcopy

        If outfile is a string, it is interpreted as a file name.
        If the extension matches .ep* write encapsulated postscript,
        otherwise write a stand-alone PostScript file.

        If outfile is a file object, a stand-alone PostScript file is
        written into this file object.
        """
        isEPSF = format == 'eps'
        passed_in_file_object = False
        if is_string_like(outfile):
            title = outfile
            tmpfile = os.path.join(gettempdir(), md5(outfile).hexdigest())
        elif is_writable_file_like(outfile):
            title = None
            tmpfile = os.path.join(gettempdir(), md5(str(hash(outfile))).hexdigest())
            passed_in_file_object = True
        else:
            raise ValueError("outfile must be a path or a file-like object")
        fh = file(tmpfile, 'w')

        # find the appropriate papertype
        width, height = self.figure.get_size_inches()
        if papertype == 'auto':
            if isLandscape: papertype = _get_papertype(height, width)
            else: papertype = _get_papertype(width, height)

        if isLandscape: paperHeight, paperWidth = papersize[papertype]
        else: paperWidth, paperHeight = papersize[papertype]

        if rcParams['ps.usedistiller'] and not papertype == 'auto':
            # distillers will improperly clip eps files if the pagesize is
            # too small
            if width>paperWidth or height>paperHeight:
                if isLandscape:
                    papertype = _get_papertype(height, width)
                    paperHeight, paperWidth = papersize[papertype]
                else:
                    papertype = _get_papertype(width, height)
                    paperWidth, paperHeight = papersize[papertype]

        # center the figure on the paper
        xo = 72*0.5*(paperWidth - width)
        yo = 72*0.5*(paperHeight - height)

        l, b, w, h = self.figure.bbox.bounds
        llx = xo
        lly = yo
        urx = llx + w
        ury = lly + h
        rotation = 0
        if isLandscape:
            llx, lly, urx, ury = lly, llx, ury, urx
            xo, yo = 72*paperHeight - yo, xo
            rotation = 90
        bbox = (llx, lly, urx, ury)

        # generate PostScript code for the figure and store it in a string
        origfacecolor = self.figure.get_facecolor()
        origedgecolor = self.figure.get_edgecolor()
        self.figure.set_facecolor(facecolor)
        self.figure.set_edgecolor(edgecolor)

        self._pswriter = StringIO()
        renderer = RendererPS(width, height, self._pswriter, imagedpi=dpi)
        self.figure.draw(renderer)

        self.figure.set_facecolor(origfacecolor)
        self.figure.set_edgecolor(origedgecolor)

        # write the PostScript headers
        if isEPSF: print >>fh, "%!PS-Adobe-3.0 EPSF-3.0"
        else: print >>fh, "%!PS-Adobe-3.0"
        if title: print >>fh, "%%Title: "+title
        print >>fh, ("%%Creator: matplotlib version "
                     +__version__+", http://matplotlib.sourceforge.net/")
        print >>fh, "%%CreationDate: "+time.ctime(time.time())
        print >>fh, "%%Orientation: " + orientation
        if not isEPSF: print >>fh, "%%DocumentPaperSizes: "+papertype
        print >>fh, "%%%%BoundingBox: %d %d %d %d" % bbox
        if not isEPSF: print >>fh, "%%Pages: 1"
        print >>fh, "%%EndComments"

        Ndict = len(psDefs)
        print >>fh, "%%BeginProlog"
        if not rcParams['ps.useafm']:
            Ndict += len(renderer.used_characters)
        print >>fh, "/mpldict %d dict def"%Ndict
        print >>fh, "mpldict begin"
        for d in psDefs:
            d=d.strip()
            for l in d.split('\n'):
                print >>fh, l.strip()
        if not rcParams['ps.useafm']:
            for font_filename, chars in renderer.used_characters.values():
                if len(chars):
                    font = FT2Font(font_filename)
                    cmap = font.get_charmap()
                    glyph_ids = []
                    for c in chars:
                        gind = cmap.get(c) or 0
                        glyph_ids.append(gind)
                    # The ttf to ps (subsetting) support doesn't work for
                    # OpenType fonts that are Postscript inside (like the
                    # STIX fonts).  This will simply turn that off to avoid
                    # errors.
                    if is_opentype_cff_font(font_filename):
                        raise RuntimeError("OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend.")
                    else:
                        fonttype = rcParams['ps.fonttype']
                        convert_ttf_to_ps(font_filename, fh, rcParams['ps.fonttype'], glyph_ids)
        print >>fh, "end"
        print >>fh, "%%EndProlog"

        if not isEPSF: print >>fh, "%%Page: 1 1"
        print >>fh, "mpldict begin"
        #print >>fh, "gsave"
        print >>fh, "%s translate"%_nums_to_str(xo, yo)
        if rotation: print >>fh, "%d rotate"%rotation
        print >>fh, "%s clipbox"%_nums_to_str(width*72, height*72, 0, 0)

        # write the figure
        print >>fh, self._pswriter.getvalue()

        # write the trailer
        #print >>fh, "grestore"
        print >>fh, "end"
        print >>fh, "showpage"
        if not isEPSF: print >>fh, "%%EOF"
        fh.close()

        if rcParams['ps.usedistiller'] == 'ghostscript':
            gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
        elif rcParams['ps.usedistiller'] == 'xpdf':
            xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)

        if passed_in_file_object:
            fh = file(tmpfile)
            print >>outfile, fh.read()
        else:
            shutil.move(tmpfile, outfile)
Пример #3
0
 def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w',
                   orientation='portrait', isLandscape=False, papertype=None,
                   **kwargs):
     """
     Render the figure to hardcopy.  Set the figure patch face and
     edge colors.  This is useful because some of the GUIs have a
     gray figure face color background and you'll probably want to
     override this on hardcopy
     If outfile is a string, it is interpreted as a file name.
     If the extension matches .ep* write encapsulated postscript,
     otherwise write a stand-alone PostScript file.
     If outfile is a file object, a stand-alone PostScript file is
     written into this file object.
     """
     isEPSF = format == 'eps'
     passed_in_file_object = False
     fd, tmpfile = mkstemp()
     if is_string_like(outfile):
         title = outfile
     elif is_writable_file_like(outfile):
         title = None
         passed_in_file_object = True
     else:
         raise ValueError("outfile must be a path or a file-like object")
     os.close(fd)
     fh = file(tmpfile, 'w')
     width, height = self.figure.get_size_inches()
     if papertype == 'auto':
         if isLandscape: papertype = _get_papertype(height, width)
         else: papertype = _get_papertype(width, height)
     if isLandscape: paperHeight, paperWidth = papersize[papertype]
     else: paperWidth, paperHeight = papersize[papertype]
     if rcParams['ps.usedistiller'] and not papertype == 'auto':
         if width>paperWidth or height>paperHeight:
             if isLandscape:
                 papertype = _get_papertype(height, width)
                 paperHeight, paperWidth = papersize[papertype]
             else:
                 papertype = _get_papertype(width, height)
                 paperWidth, paperHeight = papersize[papertype]
     xo = 72*0.5*(paperWidth - width)
     yo = 72*0.5*(paperHeight - height)
     l, b, w, h = self.figure.bbox.bounds
     llx = xo
     lly = yo
     urx = llx + w
     ury = lly + h
     rotation = 0
     if isLandscape:
         llx, lly, urx, ury = lly, llx, ury, urx
         xo, yo = 72*paperHeight - yo, xo
         rotation = 90
     bbox = (llx, lly, urx, ury)
     origfacecolor = self.figure.get_facecolor()
     origedgecolor = self.figure.get_edgecolor()
     self.figure.set_facecolor(facecolor)
     self.figure.set_edgecolor(edgecolor)
     dryrun = kwargs.get("dryrun", False)
     if dryrun:
         class NullWriter(object):
             def write(self, *kl, **kwargs):
                 pass
         self._pswriter = NullWriter()
     else:
         self._pswriter = StringIO()
     _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
     ps_renderer = RendererPS(width, height, self._pswriter, imagedpi=dpi)
     renderer = MixedModeRenderer(self.figure,
         width, height, dpi, ps_renderer,
         bbox_inches_restore=_bbox_inches_restore)
     self.figure.draw(renderer)
     if dryrun: # return immediately if dryrun (tightbbox=True)
         return
     self.figure.set_facecolor(origfacecolor)
     self.figure.set_edgecolor(origedgecolor)
     if isEPSF: print >>fh, "%!PS-Adobe-3.0 EPSF-3.0"
     else: print >>fh, "%!PS-Adobe-3.0"
     if title: print >>fh, "%%Title: "+title
     print >>fh, ("%%Creator: matplotlib version "
                  +__version__+", http://matplotlib.sourceforge.net/")
     print >>fh, "%%CreationDate: "+time.ctime(time.time())
     print >>fh, "%%Orientation: " + orientation
     if not isEPSF: print >>fh, "%%DocumentPaperSizes: "+papertype
     print >>fh, "%%%%BoundingBox: %d %d %d %d" % bbox
     if not isEPSF: print >>fh, "%%Pages: 1"
     print >>fh, "%%EndComments"
     Ndict = len(psDefs)
     print >>fh, "%%BeginProlog"
     if not rcParams['ps.useafm']:
         Ndict += len(ps_renderer.used_characters)
     print >>fh, "/mpldict %d dict def"%Ndict
     print >>fh, "mpldict begin"
     for d in psDefs:
         d=d.strip()
         for l in d.split('\n'):
             print >>fh, l.strip()
     if not rcParams['ps.useafm']:
         for font_filename, chars in ps_renderer.used_characters.values():
             if len(chars):
                 font = FT2Font(font_filename)
                 cmap = font.get_charmap()
                 glyph_ids = []
                 for c in chars:
                     gind = cmap.get(c) or 0
                     glyph_ids.append(gind)
                 if is_opentype_cff_font(font_filename):
                     raise RuntimeError("OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend.")
                 else:
                     fonttype = rcParams['ps.fonttype']
                     convert_ttf_to_ps(font_filename, fh, rcParams['ps.fonttype'], glyph_ids)
     print >>fh, "end"
     print >>fh, "%%EndProlog"
     if not isEPSF: print >>fh, "%%Page: 1 1"
     print >>fh, "mpldict begin"
     print >>fh, "%s translate"%_nums_to_str(xo, yo)
     if rotation: print >>fh, "%d rotate"%rotation
     print >>fh, "%s clipbox"%_nums_to_str(width*72, height*72, 0, 0)
     print >>fh, self._pswriter.getvalue()
     print >>fh, "end"
     print >>fh, "showpage"
     if not isEPSF: print >>fh, "%%EOF"
     fh.close()
     if rcParams['ps.usedistiller'] == 'ghostscript':
         gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
     elif rcParams['ps.usedistiller'] == 'xpdf':
         xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
     if passed_in_file_object:
         fh = file(tmpfile)
         print >>outfile, fh.read()
     else:
         shutil.move(tmpfile, outfile)
Пример #4
0
        def print_figure_impl(fh):
            # write the PostScript headers
            if is_eps:
                print("%!PS-Adobe-3.0 EPSF-3.0", file=fh)
            else:
                print(
                    f"%!PS-Adobe-3.0\n"
                    f"%%DocumentPaperSizes: {papertype}\n"
                    f"%%Pages: 1\n",
                    end="",
                    file=fh)
            if title:
                print("%%Title: " + title, file=fh)
            # get source date from SOURCE_DATE_EPOCH, if set
            # See https://reproducible-builds.org/specs/source-date-epoch/
            source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
            if source_date_epoch:
                source_date = datetime.datetime.utcfromtimestamp(
                    int(source_date_epoch)).strftime("%a %b %d %H:%M:%S %Y")
            else:
                source_date = time.ctime()
            print(
                f"%%Creator: {creator_str}\n"
                f"%%CreationDate: {source_date}\n"
                f"%%Orientation: {orientation.name}\n"
                f"%%BoundingBox: {bbox[0]} {bbox[1]} {bbox[2]} {bbox[3]}\n"
                f"%%EndComments\n",
                end="",
                file=fh)

            Ndict = len(psDefs)
            print("%%BeginProlog", file=fh)
            if not mpl.rcParams['ps.useafm']:
                Ndict += len(ps_renderer._character_tracker.used)
            print("/mpldict %d dict def" % Ndict, file=fh)
            print("mpldict begin", file=fh)
            for d in psDefs:
                d = d.strip()
                for l in d.split('\n'):
                    print(l.strip(), file=fh)
            if not mpl.rcParams['ps.useafm']:
                for font_path, chars \
                        in ps_renderer._character_tracker.used.items():
                    if not chars:
                        continue
                    font = get_font(font_path)
                    glyph_ids = [font.get_char_index(c) for c in chars]
                    fonttype = mpl.rcParams['ps.fonttype']
                    # Can't use more than 255 chars from a single Type 3 font.
                    if len(glyph_ids) > 255:
                        fonttype = 42
                    # The ttf to ps (subsetting) support doesn't work for
                    # OpenType fonts that are Postscript inside (like the STIX
                    # fonts).  This will simply turn that off to avoid errors.
                    if is_opentype_cff_font(font_path):
                        raise RuntimeError(
                            "OpenType CFF fonts can not be saved using "
                            "the internal Postscript backend at this "
                            "time; consider using the Cairo backend")
                    fh.flush()
                    try:
                        convert_ttf_to_ps(os.fsencode(font_path), fh, fonttype,
                                          glyph_ids)
                    except RuntimeError:
                        _log.warning("The PostScript backend does not "
                                     "currently support the selected font.")
                        raise
            print("end", file=fh)
            print("%%EndProlog", file=fh)

            if not is_eps:
                print("%%Page: 1 1", file=fh)
            print("mpldict begin", file=fh)

            print("%s translate" % _nums_to_str(xo, yo), file=fh)
            if rotation:
                print("%d rotate" % rotation, file=fh)
            print("%s clipbox" % _nums_to_str(width * 72, height * 72, 0, 0),
                  file=fh)

            # write the figure
            content = self._pswriter.getvalue()
            if not isinstance(content, str):
                content = content.decode('ascii')
            print(content, file=fh)

            # write the trailer
            print("end", file=fh)
            print("showpage", file=fh)
            if not is_eps:
                print("%%EOF", file=fh)
            fh.flush()
Пример #5
0
    def _print_figure(self,
                      outfile,
                      format,
                      dpi=72,
                      facecolor='w',
                      edgecolor='w',
                      orientation='portrait',
                      isLandscape=False,
                      papertype=None):
        """
        Render the figure to hardcopy.  Set the figure patch face and
        edge colors.  This is useful because some of the GUIs have a
        gray figure face color background and you'll probably want to
        override this on hardcopy

        If outfile is a string, it is interpreted as a file name.
        If the extension matches .ep* write encapsulated postscript,
        otherwise write a stand-alone PostScript file.

        If outfile is a file object, a stand-alone PostScript file is
        written into this file object.
        """
        isEPSF = format == 'eps'
        passed_in_file_object = False
        if is_string_like(outfile):
            title = outfile
            tmpfile = os.path.join(gettempdir(), md5(outfile).hexdigest())
        elif is_writable_file_like(outfile):
            title = None
            tmpfile = os.path.join(gettempdir(),
                                   md5(str(hash(outfile))).hexdigest())
            passed_in_file_object = True
        else:
            raise ValueError("outfile must be a path or a file-like object")
        fh = file(tmpfile, 'w')

        # find the appropriate papertype
        width, height = self.figure.get_size_inches()
        if papertype == 'auto':
            if isLandscape: papertype = _get_papertype(height, width)
            else: papertype = _get_papertype(width, height)

        if isLandscape: paperHeight, paperWidth = papersize[papertype]
        else: paperWidth, paperHeight = papersize[papertype]

        if rcParams['ps.usedistiller'] and not papertype == 'auto':
            # distillers will improperly clip eps files if the pagesize is
            # too small
            if width > paperWidth or height > paperHeight:
                if isLandscape:
                    papertype = _get_papertype(height, width)
                    paperHeight, paperWidth = papersize[papertype]
                else:
                    papertype = _get_papertype(width, height)
                    paperWidth, paperHeight = papersize[papertype]

        # center the figure on the paper
        xo = 72 * 0.5 * (paperWidth - width)
        yo = 72 * 0.5 * (paperHeight - height)

        l, b, w, h = self.figure.bbox.bounds
        llx = xo
        lly = yo
        urx = llx + w
        ury = lly + h
        rotation = 0
        if isLandscape:
            llx, lly, urx, ury = lly, llx, ury, urx
            xo, yo = 72 * paperHeight - yo, xo
            rotation = 90
        bbox = (llx, lly, urx, ury)

        # generate PostScript code for the figure and store it in a string
        origfacecolor = self.figure.get_facecolor()
        origedgecolor = self.figure.get_edgecolor()
        self.figure.set_facecolor(facecolor)
        self.figure.set_edgecolor(edgecolor)

        self._pswriter = StringIO()
        renderer = RendererPS(width, height, self._pswriter, imagedpi=dpi)
        self.figure.draw(renderer)

        self.figure.set_facecolor(origfacecolor)
        self.figure.set_edgecolor(origedgecolor)

        # write the PostScript headers
        if isEPSF: print >> fh, "%!PS-Adobe-3.0 EPSF-3.0"
        else: print >> fh, "%!PS-Adobe-3.0"
        if title: print >> fh, "%%Title: " + title
        print >> fh, ("%%Creator: matplotlib version " + __version__ +
                      ", http://matplotlib.sourceforge.net/")
        print >> fh, "%%CreationDate: " + time.ctime(time.time())
        print >> fh, "%%Orientation: " + orientation
        if not isEPSF: print >> fh, "%%DocumentPaperSizes: " + papertype
        print >> fh, "%%%%BoundingBox: %d %d %d %d" % bbox
        if not isEPSF: print >> fh, "%%Pages: 1"
        print >> fh, "%%EndComments"

        Ndict = len(psDefs)
        print >> fh, "%%BeginProlog"
        if not rcParams['ps.useafm']:
            Ndict += len(renderer.used_characters)
        print >> fh, "/mpldict %d dict def" % Ndict
        print >> fh, "mpldict begin"
        for d in psDefs:
            d = d.strip()
            for l in d.split('\n'):
                print >> fh, l.strip()
        if not rcParams['ps.useafm']:
            for font_filename, chars in renderer.used_characters.values():
                if len(chars):
                    font = FT2Font(font_filename)
                    cmap = font.get_charmap()
                    glyph_ids = []
                    for c in chars:
                        gind = cmap.get(c) or 0
                        glyph_ids.append(gind)
                    # The ttf to ps (subsetting) support doesn't work for
                    # OpenType fonts that are Postscript inside (like the
                    # STIX fonts).  This will simply turn that off to avoid
                    # errors.
                    if is_opentype_cff_font(font_filename):
                        raise RuntimeError(
                            "OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend."
                        )
                    else:
                        fonttype = rcParams['ps.fonttype']
                        convert_ttf_to_ps(font_filename, fh,
                                          rcParams['ps.fonttype'], glyph_ids)
        print >> fh, "end"
        print >> fh, "%%EndProlog"

        if not isEPSF: print >> fh, "%%Page: 1 1"
        print >> fh, "mpldict begin"
        #print >>fh, "gsave"
        print >> fh, "%s translate" % _nums_to_str(xo, yo)
        if rotation: print >> fh, "%d rotate" % rotation
        print >> fh, "%s clipbox" % _nums_to_str(width * 72, height * 72, 0, 0)

        # write the figure
        print >> fh, self._pswriter.getvalue()

        # write the trailer
        #print >>fh, "grestore"
        print >> fh, "end"
        print >> fh, "showpage"
        if not isEPSF: print >> fh, "%%EOF"
        fh.close()

        if rcParams['ps.usedistiller'] == 'ghostscript':
            gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
        elif rcParams['ps.usedistiller'] == 'xpdf':
            xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)

        if passed_in_file_object:
            fh = file(tmpfile)
            print >> outfile, fh.read()
        else:
            shutil.move(tmpfile, outfile)