예제 #1
0
    def draw_path_collection(self, gc, master_transform, paths, all_transforms,
                             offsets, offsetTrans, facecolors, edgecolors,
                             linewidths, linestyles, antialiaseds, urls,
                             offset_position):
        # Is the optimization worth it? Rough calculation:
        # cost of emitting a path in-line is
        #    (len_path + 5) * uses_per_path
        # cost of definition+use is
        #    (len_path + 3) + 9 * uses_per_path
        len_path = len(paths[0].vertices) if len(paths) > 0 else 0
        uses_per_path = self._iter_collection_uses_per_path(
            paths, all_transforms, offsets, facecolors, edgecolors)
        should_do_optimization = \
            len_path + 9 * uses_per_path + 3 < (len_path + 5) * uses_per_path
        if not should_do_optimization:
            return RendererBase.draw_path_collection(
                self, gc, master_transform, paths, all_transforms,
                offsets, offsetTrans, facecolors, edgecolors,
                linewidths, linestyles, antialiaseds, urls,
                offset_position)

        writer = self.writer
        path_codes = []
        writer.start('defs')
        for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
            master_transform, paths, all_transforms)):
            transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0)
            d = self._convert_path(path, transform, simplify=False)
            oid = 'C%x_%x_%s' % (self._path_collection_id, i,
                                  self._make_id('', d))
            writer.element('path', id=oid, d=d)
            path_codes.append(oid)
        writer.end('defs')

        for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
            gc, master_transform, all_transforms, path_codes, offsets,
            offsetTrans, facecolors, edgecolors, linewidths, linestyles,
            antialiaseds, urls, offset_position):
            clipid = self._get_clip(gc0)
            url = gc0.get_url()
            if url is not None:
                writer.start('a', attrib={'xlink:href': url})
            if clipid is not None:
                writer.start('g', attrib={'clip-path': 'url(#%s)' % clipid})
            attrib = {
                'xlink:href': '#%s' % path_id,
                'x': short_float_fmt(xo),
                'y': short_float_fmt(self.height - yo),
                'style': self._get_style(gc0, rgbFace)
                }
            writer.element('use', attrib=attrib)
            if clipid is not None:
                writer.end('g')
            if url is not None:
                writer.end('a')

        self._path_collection_id += 1
예제 #2
0
    def draw_path_collection(self, gc, master_transform, paths, all_transforms,
                             offsets, offsetTrans, facecolors, edgecolors,
                             linewidths, linestyles, antialiaseds, urls,
                             offset_position):
        # Is the optimization worth it? Rough calculation:
        # cost of emitting a path in-line is
        #    (len_path + 5) * uses_per_path
        # cost of definition+use is
        #    (len_path + 3) + 9 * uses_per_path
        len_path = len(paths[0].vertices) if len(paths) > 0 else 0
        uses_per_path = self._iter_collection_uses_per_path(
            paths, all_transforms, offsets, facecolors, edgecolors)
        should_do_optimization = \
            len_path + 9 * uses_per_path + 3 < (len_path + 5) * uses_per_path
        if not should_do_optimization:
            return RendererBase.draw_path_collection(
                self, gc, master_transform, paths, all_transforms, offsets,
                offsetTrans, facecolors, edgecolors, linewidths, linestyles,
                antialiaseds, urls, offset_position)

        writer = self.writer
        path_codes = []
        writer.start('defs')
        for i, (path, transform) in enumerate(
                self._iter_collection_raw_paths(master_transform, paths,
                                                all_transforms)):
            transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0)
            d = self._convert_path(path, transform, simplify=False)
            oid = 'C%x_%x_%s' % (self._path_collection_id, i,
                                 self._make_id('', d))
            writer.element('path', id=oid, d=d)
            path_codes.append(oid)
        writer.end('defs')

        for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
                gc, master_transform, all_transforms, path_codes, offsets,
                offsetTrans, facecolors, edgecolors, linewidths, linestyles,
                antialiaseds, urls, offset_position):
            clipid = self._get_clip(gc0)
            url = gc0.get_url()
            if url is not None:
                writer.start('a', attrib={'xlink:href': url})
            if clipid is not None:
                writer.start('g', attrib={'clip-path': 'url(#%s)' % clipid})
            attrib = {
                'xlink:href': '#%s' % path_id,
                'x': short_float_fmt(xo),
                'y': short_float_fmt(self.height - yo),
                'style': self._get_style(gc0, rgbFace)
            }
            writer.element('use', attrib=attrib)
            if clipid is not None:
                writer.end('g')
            if url is not None:
                writer.end('a')

        self._path_collection_id += 1
예제 #3
0
 def draw_path_collection(self, gc, master_transform, paths, all_transforms,
                          offsets, offsetTrans, facecolors, edgecolors,
                          linewidths, linestyles, antialiaseds, urls,
                          offset_position):
     '''Draws a collection of paths selecting drawing properties from
        the lists *facecolors*, *edgecolors*, *linewidths*,
        *linestyles* and *antialiaseds*. *offsets* is a list of
        offsets to apply to each of the paths. The offsets in
        *offsets* are first transformed by *offsetTrans* before being
        applied.  *offset_position* may be either "screen" or "data"
        depending on the space that the offsets are in.
     '''
     len_path = len(paths[0].vertices) if len(paths) > 0 else 0
     uses_per_path = self._iter_collection_uses_per_path(
         paths, all_transforms, offsets, facecolors, edgecolors)
     # check whether an optimization is needed by calculating the cost of
     # generating and use a path with the cost of emitting a path in-line.
     should_do_optimization = \
         len_path + uses_per_path + 5 < len_path * uses_per_path
     if not should_do_optimization:
         return RendererBase.draw_path_collection(
             self, gc, master_transform, paths, all_transforms, offsets,
             offsetTrans, facecolors, edgecolors, linewidths, linestyles,
             antialiaseds, urls, offset_position)
     # Generate an array of unique paths with the respective transformations
     path_codes = []
     for i, (path, transform) in enumerate(
             self._iter_collection_raw_paths(master_transform, paths,
                                             all_transforms)):
         transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0)
         if _mpl_ge_2_0:
             polygons = path.to_polygons(transform, closed_only=False)
         else:
             polygons = path.to_polygons(transform)
         path_codes.append(polygons)
     # Apply the styles and rgbFace to each one of the raw paths from
     # the list. Additionally a transformation is being applied to
     # translate each independent path
     for xo, yo, path_poly, gc0, rgbFace in self._iter_collection(
             gc, master_transform, all_transforms, path_codes, offsets,
             offsetTrans, facecolors, edgecolors, linewidths, linestyles,
             antialiaseds, urls, offset_position):
         list_canvas_instruction = self.get_path_instructions(
             gc0, path_poly, closed=True, rgbFace=rgbFace)
         for widget, instructions in list_canvas_instruction:
             widget.canvas.add(PushMatrix())
             widget.canvas.add(Translate(xo, yo))
             widget.canvas.add(instructions)
             widget.canvas.add(PopMatrix())
예제 #4
0
 def draw_path_collection(self, gc, master_transform, paths, all_transforms,
     offsets, offsetTrans, facecolors, edgecolors,
     linewidths, linestyles, antialiaseds, urls,
     offset_position):
     '''Draws a collection of paths selecting drawing properties from
        the lists *facecolors*, *edgecolors*, *linewidths*,
        *linestyles* and *antialiaseds*. *offsets* is a list of
        offsets to apply to each of the paths. The offsets in
        *offsets* are first transformed by *offsetTrans* before being
        applied.  *offset_position* may be either "screen" or "data"
        depending on the space that the offsets are in.
     '''
     len_path = len(paths[0].vertices) if len(paths) > 0 else 0
     uses_per_path = self._iter_collection_uses_per_path(
         paths, all_transforms, offsets, facecolors, edgecolors)
     # check whether an optimization is needed by calculating the cost of
     # generating and use a path with the cost of emitting a path in-line.
     should_do_optimization = \
         len_path + uses_per_path + 5 < len_path * uses_per_path
     if not should_do_optimization:
         return RendererBase.draw_path_collection(
             self, gc, master_transform, paths, all_transforms,
             offsets, offsetTrans, facecolors, edgecolors,
             linewidths, linestyles, antialiaseds, urls,
             offset_position)
     # Generate an array of unique paths with the respective transformations
     path_codes = []
     for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
         master_transform, paths, all_transforms)):
         transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0)
         if _mpl_ge_2_0:
             polygons = path.to_polygons(transform, closed_only=False)
         else:
             polygons = path.to_polygons(transform)
         path_codes.append(polygons)
     # Apply the styles and rgbFace to each one of the raw paths from
     # the list. Additionally a transformation is being applied to
     # translate each independent path
     for xo, yo, path_poly, gc0, rgbFace in self._iter_collection(
         gc, master_transform, all_transforms, path_codes, offsets,
         offsetTrans, facecolors, edgecolors, linewidths, linestyles,
         antialiaseds, urls, offset_position):
         list_canvas_instruction = self.get_path_instructions(gc0, path_poly,
                                 closed=True, rgbFace=rgbFace)
         for widget, instructions in list_canvas_instruction:
             widget.canvas.add(PushMatrix())
             widget.canvas.add(Translate(xo, yo))
             widget.canvas.add(instructions)
             widget.canvas.add(PopMatrix())
    def draw_path_collection(self, gc, main_transform, paths, *args, **kwargs):
        # We do a little shimmy so that all paths are drawn for each path
        # effect in turn. Essentially, we induce recursion (depth 1) which is
        # terminated once we have just a single path effect to work with.
        if len(self._path_effects) == 1:
            # Call the base path effect function - this uses the unoptimised
            # approach of calling "draw_path" multiple times.
            return RendererBase.draw_path_collection(self, gc, main_transform,
                                                     paths, *args, **kwargs)

        for path_effect in self._path_effects:
            renderer = self.copy_with_path_effect([path_effect])
            # Recursively call this method, only next time we will only have
            # one path effect.
            renderer.draw_path_collection(gc, main_transform, paths, *args,
                                          **kwargs)
예제 #6
0
    def draw_path_collection(self, gc, master_transform, paths, all_transforms,
                             offsets, offsetTrans, facecolors, edgecolors,
                             linewidths, linestyles, antialiaseds, urls,
                             offset_position):
        # Is the optimization worth it? Rough calculation:
        # cost of emitting a path in-line is
        #     (len_path + 2) * uses_per_path
        # cost of definition+use is
        #     (len_path + 3) + 3 * uses_per_path
        len_path = len(paths[0].vertices) if len(paths) > 0 else 0
        uses_per_path = self._iter_collection_uses_per_path(
            paths, all_transforms, offsets, facecolors, edgecolors)
        should_do_optimization = \
            len_path + 3 * uses_per_path + 3 < (len_path + 2) * uses_per_path
        if not should_do_optimization:
            return RendererBase.draw_path_collection(
                self, gc, master_transform, paths, all_transforms,
                offsets, offsetTrans, facecolors, edgecolors,
                linewidths, linestyles, antialiaseds, urls,
                offset_position)

        write = self._pswriter.write

        path_codes = []
        for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
                master_transform, paths, all_transforms)):
            name = 'p%x_%x' % (self._path_collection_id, i)
            path_bytes = self._convert_path(path, transform, simplify=False)
            write(f"""\
/{name} {{
newpath
translate
{path_bytes}
}} bind def
""")
            path_codes.append(name)

        for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
                gc, master_transform, all_transforms, path_codes, offsets,
                offsetTrans, facecolors, edgecolors, linewidths, linestyles,
                antialiaseds, urls, offset_position):
            ps = "%g %g %s" % (xo, yo, path_id)
            self._draw_ps(ps, gc0, rgbFace)

        self._path_collection_id += 1
예제 #7
0
    def draw_path_collection(self, gc, master_transform, paths, *args,
                             **kwargs):
        # We do a little shimmy so that all paths are drawn for each path
        # effect in turn. Essentially, we induce recursion (depth 1) which is
        # terminated once we have just a single path effect to work with.
        if len(self._path_effects) == 1:
            # Call the base path effect function - this uses the unoptimised
            # approach of calling "draw_path" multiple times.
            return RendererBase.draw_path_collection(self, gc,
                                                     master_transform, paths,
                                                     *args, **kwargs)

        for path_effect in self._path_effects:
            renderer = self.copy_with_path_effect([path_effect])
            # Recursively call this method, only next time we will only have
            # one path effect.
            renderer.draw_path_collection(gc, master_transform, paths,
                                          *args, **kwargs)