예제 #1
0
    def draw_3d_collection(self, **props):
        """Draw 3D collection for scatter plots"""
        line, marker = {}, {}
        if props['linestyle'] and props['markerstyle']:
            mode = 'lines+markers'
        elif props['linestyle']:
            mode = 'lines'
        elif props['markerstyle']:
            mode = 'markers'
        if props['linestyle']:
            color = mpltools.merge_color_and_opacity(
                props['linestyle']['color'], props['linestyle']['alpha'])
            line = go.scatter3d.Line(color=color,
                                     width=props['linestyle']['linewidth'],
                                     dash=mpltools.convert_dash(
                                         props["linestyle"]["dasharray"]))

        if props['markerstyle']:
            marker = go.scatter3d.Marker(
                opacity=props["markerstyle"]["alpha"],
                color=props["markerstyle"]["facecolor"],
                symbol=get_symbol_3d(props["markerstyle"]["marker"]),
                size=props["markerstyle"]["markersize"],
                line=dict(
                    color=props["markerstyle"]["edgecolor"],
                    width=props["markerstyle"]["edgewidth"],
                ),
            )

        if props["coordinates"] == "data":
            scatter_plot = go.Scatter3d(
                mode=mode,
                name=(str(props["label"]) if isinstance(
                    props["label"], six.string_types) else props["label"]),
                x=[xyz_pair[0] for xyz_pair in props["data"]],
                y=[xyz_pair[1] for xyz_pair in props["data"]],
                z=[xyz_pair[2] for xyz_pair in props["data"]],
                scene='scene{}'.format(self.axis_ct),
                line=line,
                marker=marker,
            )
            if self.x_is_mpl_date:
                formatter = (self.current_mpl_ax.get_xaxis().
                             get_major_formatter().__class__.__name__)

                scatter_plot["x"] = mpltools.mpl_dates_to_datestrings(
                    scatter_plot["x"], formatter)

            self.plotly_fig.add_trace(scatter_plot)
예제 #2
0
    def draw_marked_line(self, **props):
        """Create a data dict for a line obj.

        This will draw 'lines', 'markers', or 'lines+markers'.

        props.keys() -- [
        'coordinates',  ('data', 'axes', 'figure', or 'display')
        'data',         (a list of xy pairs)
        'mplobj',       (the matplotlib.lines.Line2D obj being rendered)
        'label',        (the name of the Line2D obj being rendered)
        'linestyle',    (linestyle dict, can be None, see below)
        'markerstyle',  (markerstyle dict, can be None, see below)
        ]

        props['linestyle'].keys() -- [
        'alpha',        (opacity of Line2D obj)
        'color',        (color of the line if it exists, not the marker)
        'linewidth',
        'dasharray',    (code for linestyle, see DASH_MAP in mpltools.py)
        'zorder',       (viewing precedence when stacked with other objects)
        ]

        props['markerstyle'].keys() -- [
        'alpha',        (opacity of Line2D obj)
        'marker',       (the mpl marker symbol, see SYMBOL_MAP in mpltools.py)
        'facecolor',    (color of the marker face)
        'edgecolor',    (color of the marker edge)
        'edgewidth',    (width of marker edge)
        'markerpath',   (an SVG path for drawing the specified marker)
        'zorder',       (viewing precedence when stacked with other objects)
        ]

        """
        self.msg += "    Attempting to draw a line "
        line, marker = {}, {}
        if props['linestyle'] and props['markerstyle']:
            self.msg += "... with both lines+markers\n"
            mode = "lines+markers"
        elif props['linestyle']:
            self.msg += "... with just lines\n"
            mode = "lines"
        elif props['markerstyle']:
            self.msg += "... with just markers\n"
            mode = "markers"
        if props['linestyle']:
            color = \
                mpltools.merge_color_and_opacity(props['linestyle']['color'],
                                                 props['linestyle']['alpha'])

            #print(mpltools.convert_dash(props['linestyle']['dasharray']))
            line = go.scatter.Line(
                color=color,
                width=props['linestyle']['linewidth'],
                dash=mpltools.convert_dash(props['linestyle']['dasharray'])
            )
        if props['markerstyle']:
            marker = go.scatter.Marker(
                opacity=props['markerstyle']['alpha'],
                color=props['markerstyle']['facecolor'],
                symbol=mpltools.convert_symbol(props['markerstyle']['marker']),
                size=props['markerstyle']['markersize'],
                line=dict(
                    color=props['markerstyle']['edgecolor'],
                    width=props['markerstyle']['edgewidth']
                )
            )
        if props['coordinates'] == 'data':
            marked_line = go.Scatter(
                mode=mode,
                name=(str(props['label']) if
                      isinstance(props['label'], six.string_types) else
                      props['label']),
                x=[xy_pair[0] for xy_pair in props['data']],
                y=[xy_pair[1] for xy_pair in props['data']],
                xaxis='x{0}'.format(self.axis_ct),
                yaxis='y{0}'.format(self.axis_ct),
                line=line,
                marker=marker)
            if self.x_is_mpl_date:
                formatter = (self.current_mpl_ax.get_xaxis()
                             .get_major_formatter().__class__.__name__)
                marked_line['x'] = mpltools.mpl_dates_to_datestrings(
                    marked_line['x'], formatter
                )
            self.plotly_fig.add_trace(marked_line),
            self.msg += "    Heck yeah, I drew that line\n"
        else:
            self.msg += "    Line didn't have 'data' coordinates, " \
                        "not drawing\n"
            warnings.warn("Bummer! Plotly can currently only draw Line2D "
                          "objects from matplotlib that are in 'data' "
                          "coordinates!")
예제 #3
0
    def draw_bar(self, coll):
        """Draw a collection of similar patches as a bar chart.

        After bars are sorted, an appropriate data dictionary must be created
        to tell plotly about this data. Just like draw_line or draw_markers,
        draw_bar translates patch/path information into something plotly
        understands.

        Positional arguments:
        patch_coll -- a collection of patches to be drawn as a bar chart.

        """
        tol = 1e-10
        trace = [mpltools.make_bar(**bar_props) for bar_props in coll]
        widths = [bar_props['x1'] - bar_props['x0'] for bar_props in trace]
        heights = [bar_props['y1'] - bar_props['y0'] for bar_props in trace]
        vertical = abs(
            sum(widths[0] - widths[iii] for iii in range(len(widths)))
        ) < tol
        horizontal = abs(
            sum(heights[0] - heights[iii] for iii in range(len(heights)))
        ) < tol
        if vertical and horizontal:
            # Check for monotonic x. Can't both be true!
            x_zeros = [bar_props['x0'] for bar_props in trace]
            if all((x_zeros[iii + 1] > x_zeros[iii]
                    for iii in range(len(x_zeros[:-1])))):
                orientation = 'v'
            else:
                orientation = 'h'
        elif vertical:
            orientation = 'v'
        else:
            orientation = 'h'
        if orientation == 'v':
            self.msg += "    Attempting to draw a vertical bar chart\n"
            old_heights = [bar_props['y1'] for bar_props in trace]
            for bar in trace:
                bar['y0'], bar['y1'] = 0, bar['y1'] - bar['y0']
            new_heights = [bar_props['y1'] for bar_props in trace]
            # check if we're stacked or not...
            for old, new in zip(old_heights, new_heights):
                if abs(old - new) > tol:
                    self.plotly_fig['layout']['barmode'] = 'stack'
                    self.plotly_fig['layout']['hovermode'] = 'x'
            x = [bar['x0'] + (bar['x1'] - bar['x0']) / 2 for bar in trace]
            y = [bar['y1'] for bar in trace]
            bar_gap = mpltools.get_bar_gap([bar['x0'] for bar in trace],
                                           [bar['x1'] for bar in trace])
            if self.x_is_mpl_date:
                x = [bar['x0'] for bar in trace]
                formatter = (self.current_mpl_ax.get_xaxis()
                             .get_major_formatter().__class__.__name__)
                x = mpltools.mpl_dates_to_datestrings(x, formatter)
        else:
            self.msg += "    Attempting to draw a horizontal bar chart\n"
            old_rights = [bar_props['x1'] for bar_props in trace]
            for bar in trace:
                bar['x0'], bar['x1'] = 0, bar['x1'] - bar['x0']
            new_rights = [bar_props['x1'] for bar_props in trace]
            # check if we're stacked or not...
            for old, new in zip(old_rights, new_rights):
                if abs(old - new) > tol:
                    self.plotly_fig['layout']['barmode'] = 'stack'
                    self.plotly_fig['layout']['hovermode'] = 'y'
            x = [bar['x1'] for bar in trace]
            y = [bar['y0'] + (bar['y1'] - bar['y0']) / 2 for bar in trace]
            bar_gap = mpltools.get_bar_gap([bar['y0'] for bar in trace],
                                           [bar['y1'] for bar in trace])
        bar = go.Bar(
            orientation=orientation,
            x=x,
            y=y,
            xaxis='x{0}'.format(self.axis_ct),
            yaxis='y{0}'.format(self.axis_ct),
            opacity=trace[0]['alpha'],  # TODO: get all alphas if array?
            marker=go.bar.Marker(
                color=trace[0]['facecolor'],  # TODO: get all
                line=dict(width=trace[0]['edgewidth'])))  # TODO ditto
        if len(bar['x']) > 1:
            self.msg += "    Heck yeah, I drew that bar chart\n"
            self.plotly_fig.add_trace(bar),
            if bar_gap is not None:
                self.plotly_fig['layout']['bargap'] = bar_gap
        else:
            self.msg += "    Bar chart not drawn\n"
            warnings.warn('found box chart data with length <= 1, '
                          'assuming data redundancy, not plotting.')
예제 #4
0
    def draw_marked_line(self, **props):
        """Create a data dict for a line obj.

        This will draw 'lines', 'markers', or 'lines+markers'.

        props.keys() -- [
        'coordinates',  ('data', 'axes', 'figure', or 'display')
        'data',         (a list of xy pairs)
        'mplobj',       (the matplotlib.lines.Line2D obj being rendered)
        'label',        (the name of the Line2D obj being rendered)
        'linestyle',    (linestyle dict, can be None, see below)
        'markerstyle',  (markerstyle dict, can be None, see below)
        ]

        props['linestyle'].keys() -- [
        'alpha',        (opacity of Line2D obj)
        'color',        (color of the line if it exists, not the marker)
        'linewidth',
        'dasharray',    (code for linestyle, see DASH_MAP in mpltools.py)
        'zorder',       (viewing precedence when stacked with other objects)
        ]

        props['markerstyle'].keys() -- [
        'alpha',        (opacity of Line2D obj)
        'marker',       (the mpl marker symbol, see SYMBOL_MAP in mpltools.py)
        'facecolor',    (color of the marker face)
        'edgecolor',    (color of the marker edge)
        'edgewidth',    (width of marker edge)
        'markerpath',   (an SVG path for drawing the specified marker)
        'zorder',       (viewing precedence when stacked with other objects)
        ]

        """
        self.msg += "    Attempting to draw a line "
        line, marker = {}, {}
        if props['linestyle'] and props['markerstyle']:
            self.msg += "... with both lines+markers\n"
            mode = "lines+markers"
        elif props['linestyle']:
            self.msg += "... with just lines\n"
            mode = "lines"
        elif props['markerstyle']:
            self.msg += "... with just markers\n"
            mode = "markers"
        if props['linestyle']:
            line = go.Line(
                opacity=props['linestyle']['alpha'],
                color=props['linestyle']['color'],
                width=props['linestyle']['linewidth'],
                dash=mpltools.convert_dash(props['linestyle']['dasharray'])
            )
        if props['markerstyle']:
            marker = go.Marker(
                opacity=props['markerstyle']['alpha'],
                color=props['markerstyle']['facecolor'],
                symbol=mpltools.convert_symbol(props['markerstyle']['marker']),
                size=props['markerstyle']['markersize'],
                line=go.Line(
                    color=props['markerstyle']['edgecolor'],
                    width=props['markerstyle']['edgewidth']
                )
            )
        if props['coordinates'] == 'data':
            marked_line = go.Scatter(
                mode=mode,
                name=props['label'],
                x=[xy_pair[0] for xy_pair in props['data']],
                y=[xy_pair[1] for xy_pair in props['data']],
                xaxis='x{0}'.format(self.axis_ct),
                yaxis='y{0}'.format(self.axis_ct),
                line=line,
                marker=marker)
            if self.x_is_mpl_date:
                formatter = (self.current_mpl_ax.get_xaxis()
                             .get_major_formatter().__class__.__name__)
                marked_line['x'] = mpltools.mpl_dates_to_datestrings(
                    marked_line['x'], formatter
                )
            self.plotly_fig['data'] += marked_line,
            self.msg += "    Heck yeah, I drew that line\n"
        else:
            self.msg += "    Line didn't have 'data' coordinates, " \
                        "not drawing\n"
            warnings.warn("Bummer! Plotly can currently only draw Line2D "
                          "objects from matplotlib that are in 'data' "
                          "coordinates!")
예제 #5
0
    def draw_bar(self, coll):
        """Draw a collection of similar patches as a bar chart.

        After bars are sorted, an appropriate data dictionary must be created
        to tell plotly about this data. Just like draw_line or draw_markers,
        draw_bar translates patch/path information into something plotly
        understands.

        Positional arguments:
        patch_coll -- a collection of patches to be drawn as a bar chart.

        """
        tol = 1e-10
        trace = [mpltools.make_bar(**bar_props) for bar_props in coll]
        widths = [bar_props['x1'] - bar_props['x0'] for bar_props in trace]
        heights = [bar_props['y1'] - bar_props['y0'] for bar_props in trace]
        vertical = abs(
            sum(widths[0] - widths[iii] for iii in range(len(widths)))
        ) < tol
        horizontal = abs(
            sum(heights[0] - heights[iii] for iii in range(len(heights)))
        ) < tol
        if vertical and horizontal:
            # Check for monotonic x. Can't both be true!
            x_zeros = [bar_props['x0'] for bar_props in trace]
            if all((x_zeros[iii + 1] > x_zeros[iii]
                    for iii in range(len(x_zeros[:-1])))):
                orientation = 'v'
            else:
                orientation = 'h'
        elif vertical:
            orientation = 'v'
        else:
            orientation = 'h'
        if orientation == 'v':
            self.msg += "    Attempting to draw a vertical bar chart\n"
            old_heights = [bar_props['y1'] for bar_props in trace]
            for bar in trace:
                bar['y0'], bar['y1'] = 0, bar['y1'] - bar['y0']
            new_heights = [bar_props['y1'] for bar_props in trace]
            # check if we're stacked or not...
            for old, new in zip(old_heights, new_heights):
                if abs(old - new) > tol:
                    self.plotly_fig['layout']['barmode'] = 'stack'
                    self.plotly_fig['layout']['hovermode'] = 'x'
            x = [bar['x0'] + (bar['x1'] - bar['x0']) / 2 for bar in trace]
            y = [bar['y1'] for bar in trace]
            bar_gap = mpltools.get_bar_gap([bar['x0'] for bar in trace],
                                           [bar['x1'] for bar in trace])
            if self.x_is_mpl_date:
                x = [bar['x0'] for bar in trace]
                formatter = (self.current_mpl_ax.get_xaxis()
                             .get_major_formatter().__class__.__name__)
                x = mpltools.mpl_dates_to_datestrings(x, formatter)
        else:
            self.msg += "    Attempting to draw a horizontal bar chart\n"
            old_rights = [bar_props['x1'] for bar_props in trace]
            for bar in trace:
                bar['x0'], bar['x1'] = 0, bar['x1'] - bar['x0']
            new_rights = [bar_props['x1'] for bar_props in trace]
            # check if we're stacked or not...
            for old, new in zip(old_rights, new_rights):
                if abs(old - new) > tol:
                    self.plotly_fig['layout']['barmode'] = 'stack'
                    self.plotly_fig['layout']['hovermode'] = 'y'
            x = [bar['x1'] for bar in trace]
            y = [bar['y0'] + (bar['y1'] - bar['y0']) / 2 for bar in trace]
            bar_gap = mpltools.get_bar_gap([bar['y0'] for bar in trace],
                                           [bar['y1'] for bar in trace])
        bar = go.Bar(
            orientation=orientation,
            x=x,
            y=y,
            xaxis='x{0}'.format(self.axis_ct),
            yaxis='y{0}'.format(self.axis_ct),
            opacity=trace[0]['alpha'],  # TODO: get all alphas if array?
            marker=go.Marker(
                color=trace[0]['facecolor'],  # TODO: get all
                line=go.Line(width=trace[0]['edgewidth'])))  # TODO ditto
        if len(bar['x']) > 1:
            self.msg += "    Heck yeah, I drew that bar chart\n"
            self.plotly_fig['data'] += bar,
            if bar_gap is not None:
                self.plotly_fig['layout']['bargap'] = bar_gap
        else:
            self.msg += "    Bar chart not drawn\n"
            warnings.warn('found box chart data with length <= 1, '
                          'assuming data redundancy, not plotting.')
예제 #6
0
    def draw_marked_line(self, **props):
        """Create a data dict for a line obj.

        This will draw 'lines', 'markers', or 'lines+markers'. For legend elements,
        this will use layout.shapes, so they can be positioned with paper refs.

        props.keys() -- [
        'coordinates',  ('data', 'axes', 'figure', or 'display')
        'data',         (a list of xy pairs)
        'mplobj',       (the matplotlib.lines.Line2D obj being rendered)
        'label',        (the name of the Line2D obj being rendered)
        'linestyle',    (linestyle dict, can be None, see below)
        'markerstyle',  (markerstyle dict, can be None, see below)
        ]

        props['linestyle'].keys() -- [
        'alpha',        (opacity of Line2D obj)
        'color',        (color of the line if it exists, not the marker)
        'linewidth',
        'dasharray',    (code for linestyle, see DASH_MAP in mpltools.py)
        'zorder',       (viewing precedence when stacked with other objects)
        ]

        props['markerstyle'].keys() -- [
        'alpha',        (opacity of Line2D obj)
        'marker',       (the mpl marker symbol, see SYMBOL_MAP in mpltools.py)
        'facecolor',    (color of the marker face)
        'edgecolor',    (color of the marker edge)
        'edgewidth',    (width of marker edge)
        'markerpath',   (an SVG path for drawing the specified marker)
        'zorder',       (viewing precedence when stacked with other objects)
        ]

        """
        self.msg += "    Attempting to draw a line "
        line, marker, shape = {}, {}, {}
        if props["linestyle"] and props["markerstyle"]:
            self.msg += "... with both lines+markers\n"
            mode = "lines+markers"
        elif props["linestyle"]:
            self.msg += "... with just lines\n"
            mode = "lines"
        elif props["markerstyle"]:
            self.msg += "... with just markers\n"
            mode = "markers"
        if props["linestyle"]:
            color = mpltools.merge_color_and_opacity(
                props["linestyle"]["color"], props["linestyle"]["alpha"])

            if props["coordinates"] == "data":
                line = go.scatter.Line(
                    color=color,
                    width=props["linestyle"]["linewidth"],
                    dash=mpltools.convert_dash(
                        props["linestyle"]["dasharray"]),
                )
            else:
                shape = dict(line=dict(
                    color=color,
                    width=props["linestyle"]["linewidth"],
                    dash=mpltools.convert_dash(props["linestyle"]
                                               ["dasharray"]),
                ))
        if props["markerstyle"]:
            if props["coordinates"] == "data":
                marker = go.scatter.Marker(
                    opacity=props["markerstyle"]["alpha"],
                    color=props["markerstyle"]["facecolor"],
                    symbol=mpltools.convert_symbol(
                        props["markerstyle"]["marker"]),
                    size=props["markerstyle"]["markersize"],
                    line=dict(
                        color=props["markerstyle"]["edgecolor"],
                        width=props["markerstyle"]["edgewidth"],
                    ),
                )
            else:
                shape = dict(
                    opacity=props["markerstyle"]["alpha"],
                    fillcolor=props["markerstyle"]["facecolor"],
                    symbol=mpltools.convert_symbol(
                        props["markerstyle"]["marker"]),
                    size=props["markerstyle"]["markersize"],
                    line=dict(
                        color=props["markerstyle"]["edgecolor"],
                        width=props["markerstyle"]["edgewidth"],
                    ),
                )
        if props["coordinates"] == "data":
            marked_line = go.Scatter(
                mode=mode,
                name=(str(props["label"])
                      if isinstance(props["label"], str) else props["label"]),
                x=[xy_pair[0] for xy_pair in props["data"]],
                y=[xy_pair[1] for xy_pair in props["data"]],
                xaxis="x{0}".format(self.axis_ct),
                yaxis="y{0}".format(self.axis_ct),
                line=line,
                marker=marker,
            )
            if self.x_is_mpl_date:
                formatter = (self.current_mpl_ax.get_xaxis().
                             get_major_formatter().__class__.__name__)
                marked_line["x"] = mpltools.mpl_dates_to_datestrings(
                    marked_line["x"], formatter)
            self.plotly_fig.add_trace(marked_line),
            self.msg += "    Heck yeah, I drew that line\n"
        elif props["coordinates"] == "axes":
            # dealing with legend graphical elements
            self.draw_legend_shapes(mode=mode, shape=shape, **props)
        else:
            self.msg += "    Line didn't have 'data' coordinates, " "not drawing\n"
            warnings.warn("Bummer! Plotly can currently only draw Line2D "
                          "objects from matplotlib that are in 'data' "
                          "coordinates!")