Пример #1
0
    def _plot(self, split_gen, scales, orient):

        for keys, data, ax in split_gen(keep_na=not self._sort):

            vals = resolve_properties(self, keys, scales)
            vals["color"] = resolve_color(self, keys, scales=scales)
            vals["fillcolor"] = resolve_color(self, keys, prefix="fill", scales=scales)
            vals["edgecolor"] = resolve_color(self, keys, prefix="edge", scales=scales)

            # https://github.com/matplotlib/matplotlib/pull/16692
            if Version(mpl.__version__) < Version("3.3.0"):
                vals["marker"] = vals["marker"]._marker

            if self._sort:
                data = data.sort_values(orient)

            artist_kws = self.artist_kws.copy()
            self._handle_capstyle(artist_kws, vals)

            line = mpl.lines.Line2D(
                data["x"].to_numpy(),
                data["y"].to_numpy(),
                color=vals["color"],
                linewidth=vals["linewidth"],
                linestyle=vals["linestyle"],
                marker=vals["marker"],
                markersize=vals["pointsize"],
                markerfacecolor=vals["fillcolor"],
                markeredgecolor=vals["edgecolor"],
                markeredgewidth=vals["edgewidth"],
                **artist_kws,
            )
            ax.add_line(line)
Пример #2
0
    def _legend_artist(self, variables, value, scales):

        keys = {v: value for v in variables}
        vals = resolve_properties(self, keys, scales)
        vals["color"] = resolve_color(self, keys, scales=scales)
        vals["fillcolor"] = resolve_color(self, keys, prefix="fill", scales=scales)
        vals["edgecolor"] = resolve_color(self, keys, prefix="edge", scales=scales)

        # https://github.com/matplotlib/matplotlib/pull/16692
        if Version(mpl.__version__) < Version("3.3.0"):
            vals["marker"] = vals["marker"]._marker

        artist_kws = self.artist_kws.copy()
        self._handle_capstyle(artist_kws, vals)

        return mpl.lines.Line2D(
            [], [],
            color=vals["color"],
            linewidth=vals["linewidth"],
            linestyle=vals["linestyle"],
            marker=vals["marker"],
            markersize=vals["pointsize"],
            markerfacecolor=vals["fillcolor"],
            markeredgecolor=vals["edgecolor"],
            markeredgewidth=vals["edgewidth"],
            **artist_kws,
        )
Пример #3
0
    def _resolve_properties(self, data, scales):

        resolved = resolve_properties(self, data, scales)
        resolved["path"] = self._resolve_paths(resolved)

        if isinstance(data, dict):  # TODO need a better way to check
            filled_marker = resolved["marker"].is_filled()
        else:
            filled_marker = [m.is_filled() for m in resolved["marker"]]

        resolved["linewidth"] = resolved["stroke"]
        resolved["fill"] = resolved["fill"] * filled_marker
        resolved["size"] = resolved["pointsize"]**2

        resolved["edgecolor"] = resolve_color(self, data, "", scales)
        resolved["facecolor"] = resolve_color(self, data, "fill", scales)

        # Because only Dot, and not Scatter, has an edgestyle
        resolved.setdefault("edgestyle", (0, None))

        fc = resolved["facecolor"]
        if isinstance(fc, tuple):
            resolved["facecolor"] = fc[0], fc[1], fc[
                2], fc[3] * resolved["fill"]
        else:
            fc[:,
               3] = fc[:,
                       3] * resolved["fill"]  # TODO Is inplace mod a problem?
            resolved["facecolor"] = fc

        return resolved
Пример #4
0
    def _setup_lines(self, split_gen, scales, orient):

        line_data = {}

        other = {"x": "y", "y": "x"}[orient]

        for keys, data, ax in split_gen(keep_na=not self._sort):

            if ax not in line_data:
                line_data[ax] = {
                    "segments": [],
                    "colors": [],
                    "linewidths": [],
                    "linestyles": [],
                }

            vals = resolve_properties(self, keys, scales)
            vals["color"] = resolve_color(self, keys, scales=scales)

            cols = [orient, f"{other}min", f"{other}max"]
            data = data[cols].melt(orient, value_name=other)[["x", "y"]]
            segments = [d.to_numpy() for _, d in data.groupby(orient)]

            line_data[ax]["segments"].extend(segments)

            n = len(segments)
            line_data[ax]["colors"].extend([vals["color"]] * n)
            line_data[ax]["linewidths"].extend([vals["linewidth"]] * n)
            line_data[ax]["linestyles"].extend([vals["linestyle"]] * n)

        return line_data
Пример #5
0
    def _setup_lines(self, split_gen, scales, orient):

        line_data = {}

        for keys, data, ax in split_gen(keep_na=not self._sort):

            if ax not in line_data:
                line_data[ax] = {
                    "segments": [],
                    "colors": [],
                    "linewidths": [],
                    "linestyles": [],
                }

            vals = resolve_properties(self, keys, scales)
            vals["color"] = resolve_color(self, keys, scales=scales)

            if self._sort:
                data = data.sort_values(orient)

            # Column stack to avoid block consolidation
            xy = np.column_stack([data["x"], data["y"]])
            line_data[ax]["segments"].append(xy)
            line_data[ax]["colors"].append(vals["color"])
            line_data[ax]["linewidths"].append(vals["linewidth"])
            line_data[ax]["linestyles"].append(vals["linestyle"])

        return line_data
Пример #6
0
    def _plot(self, split_gen, scales, orient):

        kws = {}

        for keys, data, ax in split_gen():

            kws.setdefault(ax, defaultdict(list))

            data = self._standardize_coordinate_parameters(data, orient)
            resolved = resolve_properties(self, keys, scales)
            verts = self._get_verts(data, orient)

            ax.update_datalim(verts)
            kws[ax]["verts"].append(verts)

            # TODO fill= is not working here properly
            # We could hack a fix, but would be better to handle fill in resolve_color

            kws[ax]["facecolors"].append(resolve_color(self, keys, "", scales))
            kws[ax]["edgecolors"].append(
                resolve_color(self, keys, "edge", scales))

            kws[ax]["linewidth"].append(resolved["edgewidth"])
            kws[ax]["linestyle"].append(resolved["edgestyle"])

        for ax, ax_kws in kws.items():
            ax.add_collection(mpl.collections.PolyCollection(**ax_kws))
Пример #7
0
    def _plot(self, split_gen, scales, orient):

        patches = defaultdict(list)

        for keys, data, ax in split_gen():

            kws = {}
            data = self._standardize_coordinate_parameters(data, orient)
            resolved = resolve_properties(self, keys, scales)
            verts = self._get_verts(data, orient)
            ax.update_datalim(verts)

            # TODO should really move this logic into resolve_color
            fc = resolve_color(self, keys, "", scales)
            if not resolved["fill"]:
                fc = mpl.colors.to_rgba(fc, 0)

            kws["facecolor"] = fc
            kws["edgecolor"] = resolve_color(self, keys, "edge", scales)
            kws["linewidth"] = resolved["edgewidth"]
            kws["linestyle"] = resolved["edgestyle"]

            patches[ax].append(mpl.patches.Polygon(verts, **kws))

        for ax, ax_patches in patches.items():

            for patch in ax_patches:
                self._postprocess_artist(patch, ax, orient)
                ax.add_patch(patch)
Пример #8
0
    def _legend_artist(self, variables, value, scales):

        key = resolve_properties(self, {v: value for v in variables}, scales)

        return mpl.lines.Line2D(
            [],
            [],
            color=key["color"],
            linewidth=key["linewidth"],
            linestyle=key["linestyle"],
            **self.artist_kws,
        )
Пример #9
0
    def _legend_artist(self, variables, value, scales):

        keys = {v: value for v in variables}
        resolved = resolve_properties(self, keys, scales)

        return mpl.patches.Patch(
            facecolor=resolve_color(self, keys, "", scales),
            edgecolor=resolve_color(self, keys, "edge", scales),
            linewidth=resolved["edgewidth"],
            linestyle=resolved["edgestyle"],
            **self.artist_kws,
        )
Пример #10
0
    def _resolve_properties(self, data, scales):

        resolved = resolve_properties(self, data, scales)

        resolved["facecolor"] = resolve_color(self, data, "", scales)
        resolved["edgecolor"] = resolve_color(self, data, "edge", scales)

        fc = resolved["facecolor"]
        if isinstance(fc, tuple):
            resolved["facecolor"] = fc[0], fc[1], fc[2], fc[3] * resolved["fill"]
        else:
            fc[:, 3] = fc[:, 3] * resolved["fill"]  # TODO Is inplace mod a problem?
            resolved["facecolor"] = fc

        return resolved
Пример #11
0
    def _legend_artist(self, variables, value, scales):

        key = resolve_properties(self, {v: value for v in variables}, scales)

        artist_kws = self.artist_kws.copy()
        capstyle = artist_kws.pop("capstyle")
        artist_kws["solid_capstyle"] = capstyle
        artist_kws["dash_capstyle"] = capstyle

        return mpl.lines.Line2D(
            [], [],
            color=key["color"],
            linewidth=key["linewidth"],
            linestyle=key["linestyle"],
            **artist_kws,
        )
Пример #12
0
    def _plot(self, split_gen, scales, orient):

        line_data = {}

        for keys, data, ax in split_gen(keep_na=not self._sort):

            if ax not in line_data:
                line_data[ax] = {
                    "segments": [],
                    "colors": [],
                    "linewidths": [],
                    "linestyles": [],
                }

            vals = resolve_properties(self, keys, scales)
            vals["color"] = resolve_color(self, keys, scales=scales)

            if self._sort:
                data = data.sort_values(orient)

            # TODO comment about block consolidation
            xy = np.column_stack([data["x"], data["y"]])
            line_data[ax]["segments"].append(xy)
            line_data[ax]["colors"].append(vals["color"])
            line_data[ax]["linewidths"].append(vals["linewidth"])
            line_data[ax]["linestyles"].append(vals["linestyle"])

        for ax, ax_data in line_data.items():
            lines = mpl.collections.LineCollection(
                **ax_data,
                **self.artist_kws,
            )
            ax.add_collection(lines, autolim=False)
            # https://github.com/matplotlib/matplotlib/issues/23129
            # TODO get paths from lines object?
            xy = np.concatenate(ax_data["segments"])
            ax.dataLim.update_from_data_xy(xy,
                                           ax.ignore_existing_data_limits,
                                           updatex=True,
                                           updatey=True)
Пример #13
0
    def _plot(self, split_gen, scales, orient):

        for keys, data, ax in split_gen(dropna=False):

            keys = resolve_properties(self, keys, scales)

            if self.sort:
                # TODO where to dropna?
                data = data.sort_values(orient)
            else:
                data.loc[data.isna().any(axis=1), ["x", "y"]] = np.nan

            line = mpl.lines.Line2D(
                data["x"].to_numpy(),
                data["y"].to_numpy(),
                color=keys["color"],
                alpha=keys["alpha"],
                linewidth=keys["linewidth"],
                linestyle=keys["linestyle"],
                **self.
                artist_kws,  # TODO keep? remove? be consistent across marks
            )
            ax.add_line(line)