Example #1
0
 def test_layout_with_overrides(self):
     """provided layout attributes should be overridden with provided parameters"""
     layout = dict(title="layout", width=20)
     d = Drawable(layout=layout)
     fig = d.figure
     self.assertEqual(fig.layout.title, None)
     self.assertEqual(fig.layout.width, None)
     d = Drawable(layout=layout, title="parameter", width=50)
     fig = d.figure
     self.assertEqual(fig.layout.title.text, "parameter")
     self.assertEqual(fig.layout.width, 50)
Example #2
0
 def test_traces(self):
     """test trace initialisation"""
     d = Drawable()
     self.assertEqual(d.traces, [])
     trace = dict(type="scatter", x=[0, 1], y=[0, 1])
     d = Drawable(traces=[trace])
     self.assertEqual(d.traces, [trace])
     self.assertTrue(isinstance(d.traces[0], UnionDict))
     with self.assertRaises(TypeError):
         trace = dict(type="scatter", x=[0, 1], y=[0, 1])
         _ = Drawable(traces=trace)
Example #3
0
 def test_layout_with_titles(self):
     """if provided layout has axis titles, keep them"""
     layout = dict(xaxis=dict(title="X"), yaxis=dict(title="Y"))
     d = Drawable(layout=layout)
     fig = d.figure
     self.assertEqual(fig.layout.xaxis.title, "X")
     self.assertEqual(fig.layout.yaxis.title, "Y")
     d = Drawable()
     fig = d.figure
     self.assertEqual(fig.layout.xaxis.title, None)
     self.assertEqual(fig.layout.yaxis.title, None)
Example #4
0
 def test_one_trace(self):
     """should still produce a valid figure"""
     d = Drawable()
     trace = dict(type="scatter", x=[0, 1], y=[0, 1])
     d.add_trace(trace)
     f = d.figure
     self.assertEqual(f.data, [trace])
Example #5
0
 def test_add_traces(self):
     """test trace add method"""
     d = Drawable()
     self.assertEqual(d.traces, [])
     trace = dict(type="scatter", x=[0, 1], y=[0, 1])
     d.add_trace(trace)
     self.assertEqual(d.traces, [trace])
     self.assertTrue(isinstance(d.traces[0], UnionDict))
Example #6
0
 def test_figure(self):
     """figure should contain the same data and layout as Drawable"""
     trace = dict(type="scatter", x=[0, 1], y=[0, 1])
     layout = dict(title="layout", width=20)
     d = Drawable(traces=[trace], layout=layout)
     f = d.figure
     self.assertEqual(f.data, d.traces)
     self.assertEqual(f.layout, d.layout)
    def test_bound_to(self):
        """bound object should have the drawable object and show methods"""
        class TestObj:
            pass

        o = TestObj()
        d = Drawable()
        b = d.bound_to(o)
        self.assertEqual(b.drawable, d)
        self.assertTrue(hasattr(b, "iplot"))
        self.assertTrue(hasattr(b, "show"))
Example #8
0
    def to_plotly(self, width=500, font_size=12, layout=None, **kwargs):
        """returns a Plotly Table"""
        import plotly.graph_objs as go
        from cogent3.draw.drawable import Drawable

        rows = self.array.tolist()
        header, rows = table_format.formatted_cells(
            rows,
            self.header,
            digits=self._digits,
            column_templates=self._column_templates,
            missing_data=self._missing_data,
            center=False,
        )
        # we strip white space padding from header and cells
        header = [e.strip() for e in header]
        rows = [[e.strip() for e in row] for row in rows]
        rows = list(zip(*rows))
        if self._row_ids:
            body_colour = ["white"] * self.shape[0]
            index_colour = ["rgba(161, 195, 209, 0.5)"] * self.shape[0]
            colours = [index_colour
                       ] + [body_colour[:] for i in range(self.shape[1])]
            rows[0] = [f"<b>{e}</b>" for e in rows[0]]
        else:
            colours = "white"

        tab = UnionDict(
            type="table",
            header=dict(
                values=[f"<b>{c}</b>" for c in header],
                fill=dict(color="rgba(161, 195, 209, 1)"),
                font=dict(size=font_size),
                align="center",
            ),
            cells=dict(values=rows, fill=dict(color=colours)),
        )
        draw = Drawable()
        aspect_ratio = self.shape[0] / self.shape[1]
        layout = layout or {}
        default_layout = dict(
            width=width,
            height=aspect_ratio * width,
            autosize=False,
            title=self.title,
            margin=dict(l=10, r=10, t=30, b=10, pad=10),
        )
        default_layout.update(layout)
        draw.traces.append(tab)
        draw.layout |= default_layout
        return draw
Example #9
0
    def test__build_fig(self):
        """figure built should have the same traces as core and set yaxis to y3 if yaxis2 is overlaying"""
        trace = dict(type="scatter", x=[0, 1], y=[0, 1], xaxis="x", yaxis="y")
        layout = dict(title="layout", width=20, yaxis2=dict(overlaying="free"))
        cd = Drawable(traces=[trace])

        ad = AnnotatedDrawable(cd, layout=layout)
        f = ad._build_fig()
        self.assertEqual(ad._traces, f["data"])
        self.assertNotEqual(f["data"][0]["yaxis"], "y3")

        layout = dict(title="layout", width=20, yaxis2=dict(overlaying="y"))
        ad = AnnotatedDrawable(cd, layout=layout)
        f = ad._build_fig()
        self.assertEqual(f["data"][0]["yaxis"], "y3")
Example #10
0
    def get_drawable(self, width=600, vertical=False):
        """returns Drawable instance"""
        from cogent3.draw.drawable import Drawable

        drawables = self.get_drawables()
        if not drawables:
            return None
        # we order by tracks
        top = 0
        space = 0.25
        annotes = []
        for feature_type in drawables:
            new_bottom = top + space
            for i, annott in enumerate(drawables[feature_type]):
                annott.shift(y=new_bottom - annott.bottom)
                if i > 0:
                    annott._showlegend = False
                annotes.append(annott)

            top = annott.top

        top += space
        height = max((top / len(self)) * width, 300)
        xaxis = dict(range=[0, len(self)], zeroline=False, showline=True)
        yaxis = dict(range=[0, top],
                     visible=False,
                     zeroline=True,
                     showline=True)

        if vertical:
            all_traces = [t.T.as_trace() for t in annotes]
            width, height = height, width
            xaxis, yaxis = yaxis, xaxis
        else:
            all_traces = [t.as_trace() for t in annotes]

        drawer = Drawable(title=self.name,
                          traces=all_traces,
                          width=width,
                          height=height)
        drawer.layout.update(xaxis=xaxis, yaxis=yaxis)
        return drawer
Example #11
0
def grid(fig_config, figpath, format, no_type3):
    """draws an arbitrary shaped grid of mutation motifs based on fig_config"""
    # we read in the config file and determine number of rows and columns
    # paths, headings, etc ..
    # then create the figure and axes and call the mutation_motif drawing code

    args = locals()
    if no_type3:
        util.exclude_type3_fonts()

    if not figpath:
        dirname = os.path.dirname(fig_config.name)
        figpath = os.path.join(dirname, "drawn_array.%s" % format)
        log_file_path = os.path.join(dirname, "drawn_array.log")
    else:
        figpath = util.abspath(figpath)
        log_file_path = "%s.log" % ".".join(figpath.split(".")[:-1])

    util.makedirs(os.path.dirname(figpath))
    LOGGER.log_file_path = log_file_path
    LOGGER.log_message(str(args), label='vars')

    ncols, nrows, figsize, col_labels, row_labels, paths, axis_cfg = \
        read_plot_array_config(fig_config)
    print("ncols:", ncols)
    print("nrows:", nrows)
    print("figsize:", figsize)
    print("col_labels:", col_labels)
    print("row_labels:", row_labels)
    print("paths:", paths)
    print("axis_cfg:", axis_cfg)

    #TODO: Convert below into Cogent3 Plotly

    #-Plotly
    layout = UnionDict(shapes=[])
    adaptive_y = 0
    plottable = {}
    for coord in paths:
        data = util.load_loglin_stats(paths[coord])
        positions = list(data)
        positions.sort()
        heights, characters, indices = get_plot_data(data, positions)
        adaptive_y = max(adaptive_y, logo.est_ylim(heights))
        plottable[coord] = dict(char_heights=heights,
                                characters=characters,
                                position_indices=indices)

    ylim = axis_cfg.get("ylim", adaptive_y)
    for coord in plottable:
        kwargs = plottable[coord]
        kwargs["ax"] = coord
        kwargs["ylim"] = ylim
        r = logo.draw_multi_position_cogent3(**kwargs)
        for key in r:
            if key == "shapes":
                layout.shapes.extend(r.shapes)
            else:
                layout[key] = r[key]

    for i in range(0, ncols):
        xaxis = "xaxis" + str(i + 1 if i != 0 else "")
        layout[xaxis]["domain"] = [
            0.0 + (i * (1 / ncols)), (i * (1 / ncols)) + (1 / ncols)
        ]

    print(layout)
    MARGININCHES = 0
    PPI = 100
    fig = Drawable(layout=layout,
                   width=(figsize[0] - MARGININCHES) * PPI,
                   height=(figsize[1] - MARGININCHES) * PPI)

    #export
    fig.write(path=figpath)
    click.secho("Wrote Cogent3 %s" % figpath, fg="green")
    """
Example #12
0
 def test_no_trace(self):
     """should still produce a valid figure"""
     d = Drawable()
     f = d.figure
     self.assertEqual(f.data, [{}])
Example #13
0
def get_logo(
    char_heights,
    axnum=1,
    height=400,
    width=800,
    ylim=None,
    ydomain=None,
    colours=None,
    layout=None,
):
    """
    Parameters
    ----------
    char_heights
        a seris of [[(base, value), ..], ..] or series of dicts with [{letter1: value, letter2: value}, ...]
        Dicts are coerced to list of lists. If values are < 0, the letter is inverted. Empty elements are ignored.
    axnum : int
        plotly axis number
    height, width: int
        figure dimensions in pixels
    ylim : float
        maximum y-value
    ydomain
        [start, end], specifies vertical positioning for this logo
    colours : dict
        dict mapping characters to colours. Defaults to custom 'dna' colours
        typically used for DNA
    layout : UnionDict
        Customised base layout

    Returns
    -------
    Drawable
    """
    if isinstance(char_heights, DictArray) or isinstance(char_heights[0], dict):
        char_heights = _char_hts_as_lists(char_heights)

    colours = colours or _dna_colours
    if layout is None:
        layout = get_base_logo_layout(axnum, 12, 12)

    stack_data = []
    est_ylim = 0
    for d in char_heights:
        if not d:
            stack_data.append(None)
            continue

        d = sorted(d, key=lambda x: x[1])

        if ylim is None:
            est_ylim = max(est_ylim, max([e[-1] for e in d]))
        stack_data.append(d)

    stacks = []
    for index, stack in enumerate(stack_data):
        if stack is None:
            continue
        middle, stack_shapes = letter_stack(stack, index - 0.5, 1, colours, axnum)
        stacks += stack_shapes

    layout["shapes"] = stacks

    if ylim is None:
        ylim = est_ylim * 1.05

    yaxis = "yaxis" if axnum == 1 else f"yaxis{axnum}"
    layout[yaxis]["range"] = [0, ylim]
    if ydomain:
        layout[yaxis]["domain"] = ydomain

    return Drawable(layout=layout, height=height, width=width)