Esempio n. 1
0
def _plot_scores(results, methods, method_colours):
    M_sorted = list(plotter.sort_methods(methods))
    M_happy = {M: plotter.HAPPY_METHOD_NAMES.get(M, M) for M in M_sorted}

    points = {}
    runids = {}

    for M in M_sorted:
        vals = np.array([row[M] for idx, row in results.iterrows()])

        assert not np.any(vals == MISSING), '%s is missing %s' % (M, ','.join(
            results['runid'][results[M] == MISSING]))
        points[M] = vals
        runids[M] = [row['runid'] for idx, row in results.iterrows()]

    opacity = 0.5
    score_traces = [{
        'type': 'box',
        'y': points[M],
        'text': runids[M],
        'name': M_happy[M],
        'orientation': 'v',
        'boxpoints': 'all',
        'marker': {
            'outliercolor': plotter.format_colour(method_colours[M], opacity),
            'color': plotter.format_colour(method_colours[M], opacity),
            'size': 12,
        },
        'line': {
            'color': plotter.format_colour(method_colours[M]),
        },
        'jitter': 0.6,
        'pointpos': 2.0,
    } for M in points]

    max_x = max([
        calc_violin_stats(T['y'])['q2'] for T in score_traces
        if len(T['y']) > 0
    ])
    fig = {
        'data': score_traces,
        'layout': {
            'yaxis':
            dict(
                zeroline=True,
                zerolinewidth=2,
                zerolinecolor='rgba(0,0,0,0.5)',
                range=(-0.15 * max_x, 1.05 * max_x),
                title_text=
                'VAF reconstruction loss<br>(bits / mutation / tissue sample)',
            ),
            'showlegend':
            False,
        },
    }
    return fig
Esempio n. 2
0
def _plot_single_vs_others(results, single, methods, method_colours,
                           score_type):
    assert single in methods
    others = plotter.sort_methods(set(methods) - set((single, )))

    traces = []
    for M in others:
        points = [(row['runid'], row[M] - row[single]) for idx, row in results.iterrows() \
          if MISSING not in (row[single], row[M])]
        if len(points) == 0:
            continue
        runids, Y = zip(*points)
        traces.append({
            'type': 'box',
            'y': Y,
            'text': runids,
            'name': plotter.HAPPY_METHOD_NAMES.get(M, M),
            #'spanmode': 'hard',
            #'bandwidth': 0.07,
            'boxpoints': 'all',
            'marker': {
                'outliercolor': plotter.format_colour(method_colours[M], 0.5),
                'color': plotter.format_colour(method_colours[M], 0.5),
            },
            'line': {
                'color': plotter.format_colour(method_colours[M]),
            },
            'jitter': 0.6,
            'pointpos': 2.0,
        })
    fig = {
        'data': traces,
        'layout': {
            'yaxis': {
                'title':
                AXIS_TITLES[score_type]['single_vs_others'] %
                plotter.HAPPY_METHOD_NAMES.get(single, single),
                'zeroline':
                True,
                'zerolinewidth':
                1,
                'zerolinecolor':
                'rgba(0,0,0,0.3)',
            },
        },
    }

    return fig
Esempio n. 3
0
def _plot_single_vs_others(results, single, methods, method_colours):
    assert single in methods
    others = plotter.sort_methods(set(methods) - set((single, )))

    traces = []
    for M in others:
        points = [(row['runid'], row[M] - row[single]) for idx, row in results.iterrows() \
          if MISSING not in (row[single], row[M])]
        if len(points) == 0:
            continue
        runids, Y = zip(*points)
        traces.append({
            'type': 'box',
            'y': Y,
            'text': runids,
            'name': plotter.HAPPY_METHOD_NAMES.get(M, M),
            'boxpoints': 'all',
            'marker': {
                'outliercolor': plotter.format_colour(method_colours[M], 0.5),
                'color': plotter.format_colour(method_colours[M], 0.5),
            },
            'line': {
                'color': plotter.format_colour(method_colours[M]),
            },
            'jitter': 0.6,
            'pointpos': 2.0,
        })
    fig = {
        'data': traces,
        'layout': {
            'yaxis': {
                'title':
                'VAF reconstruction loss relative to %s<br>(bits / mutation / tissue sample)'
                % plotter.HAPPY_METHOD_NAMES.get(M, M),
                'zeroline':
                True,
                'zerolinewidth':
                2,
                'zerolinecolor':
                'rgba(0,0,0,0.5)',
            },
        },
    }
    return fig
Esempio n. 4
0
def _plot_success_rates(results, methods, method_colours, K_vals, S_vals):
    M_sorted = plotter.sort_methods(methods)
    M_happy = {M: plotter.HAPPY_METHOD_NAMES.get(M, M) for M in M_sorted}
    fig = plotly.subplots.make_subplots(
        rows=1,
        cols=len(K_vals),
        subplot_titles=[plotter.pluralize(K, 'subclone') for K in K_vals],
        x_title='Tissue samples',
    )

    for Kidx, K in enumerate(K_vals):
        for M in M_sorted:
            M_successes = {}
            for S in S_vals:
                KS_rows = [
                    row for idx, row in results.iterrows()
                    if row['S'] == S and row['K'] == K
                ]
                M_successes[S] = len(
                    [row
                     for row in KS_rows if row[M] != MISSING]) / len(KS_rows)

            Y = np.array([M_successes[S] for S in S_vals])
            fig.add_trace(
                {
                    'type': 'scatter',
                    'x': [str(S) for S in S_vals],
                    'y': Y,
                    'name': M_happy[M],
                    'line': {
                        'color': plotter.format_colour(method_colours[M]),
                        'width': 4,
                    },
                    'marker': {
                        'size': 14
                    },
                    'showlegend': Kidx == 0,
                },
                row=1,
                col=Kidx + 1)

    fig.update_xaxes(
        tickangle=0,
        type='category',
    )
    fig.update_yaxes(showticklabels=False, )
    fig.update_yaxes(
        title='Success rate',
        tickformat='%s%%',
        showticklabels=True,
        col=1,
    )
    return fig
Esempio n. 5
0
def _plot_S_comparison(results, methods, method_colours, K_vals, S_vals, score_type):
  M_sorted = plotter.sort_methods(methods)
  M_happy = {M: plotter.HAPPY_METHOD_NAMES.get(M, M) for M in M_sorted}
  fig = plotly.subplots.make_subplots(
    rows = 1,
    cols = len(K_vals),
    subplot_titles = [plotter.pluralize(K, 'subclone') for K in K_vals],
    x_title = 'Tissue samples',
    shared_yaxes = True,
  )

  for Kidx, K in enumerate(K_vals):
    for M in M_sorted:
      M_upper = {}
      M_error = {}
      M_lower = {}

      for S in S_vals:
        scores = np.array([row[M] for idx, row in results.iterrows() if row['S'] == S and row['K'] == K and row[M] != MISSING])
        if len(scores) == 0:
          continue
        M_lower[S] = np.quantile(scores, 0.25)
        M_upper[S] = np.quantile(scores, 0.75)
        M_error[S] = np.median(scores)

      S_present = sorted(M_error.keys())
      fig.add_trace({
        'type': 'scatter',
        'x': [str(S) for S in S_present],
        'y': [M_error[S] for S in S_present],
        'error_y': {
          'type': 'data',
          'symmetric': False,
          'array': [M_upper[S] - M_error[S] for S in S_present],
          'arrayminus': [M_error[S] - M_lower[S] for S in S_present],
        },
        'name': M_happy[M],
        'line': {'color': plotter.format_colour(method_colours[M]), 'width': 4,},
        'marker': {'size': 14},
        'showlegend': Kidx == 0,
      }, row=1, col=Kidx+1)

  fig.update_xaxes(
    tickangle = 45,
    type = 'category',
  )
  fig.update_yaxes(
    title = AXIS_TITLES[score_type]['S_comparison'],
    col = 1,
  )
  return fig
Esempio n. 6
0
def plot(results,
         unique_keys,
         result_key,
         ytitle,
         shared_y=False,
         log_y=False):
    K_vals = unique_keys['K']
    S_vals = unique_keys['S']

    fig = plotly.subplots.make_subplots(
        rows=1,
        cols=len(K_vals),
        subplot_titles=[plotter.pluralize(K, 'subclone') for K in K_vals],
        shared_yaxes=shared_y,
        x_title='Tissue samples',
        y_title=ytitle,
    )
    min_y, max_y = np.inf, -np.inf

    for Kidx, K in enumerate(K_vals):
        for S in S_vals:
            KS_rows = [
                row for idx, row in results.iterrows()
                if row['S'] == S and row['K'] == K
            ]
            if len(KS_rows) == 0:
                continue
            trace = {
                'type': 'box',
                'y': [row[result_key] for row in KS_rows],
                'text': [row['runid'] for row in KS_rows],
                'name': '%s' % S,
                'marker': {
                    'outliercolor': plotter.format_colour(S_COLOURS[S], 0.5),
                    'color': plotter.format_colour(S_COLOURS[S], 0.5),
                },
                'line': {
                    'color': plotter.format_colour(S_COLOURS[S]),
                },
            }

            #min_y = np.min([min_y, np.min(trace['y'])])
            #max_y = np.max([max_y, np.max(trace['y'])])
            #if log_y:
            #  trace['y'] = np.log10(trace['y'])
            fig.add_trace(trace, row=1, col=Kidx + 1)

    fig.update_layout(
        showlegend=False,
        title_text=ytitle,
    )
    fig.update_xaxes(
        tickangle=0,
        type='category',
    )
    if log_y:
        fig.update_yaxes(type='log')
        #floor, ceil = np.floor(np.log10(min_y)), np.ceil(np.log10(max_y)) + 1
        #N = int(ceil - floor)
        #tickvals = np.linspace(floor, ceil, num=(N+1)).astype(np.int)
        #print(tickvals, floor, ceil)
        #assert np.allclose(tickvals, tickvals.astype(np.int))
        #fig.update_yaxes(
        #  tickmode = 'array',
        #  tickvals = tickvals,
        #  ticktext = ['%s' % T for T in tickvals],
        #)

    return fig
Esempio n. 7
0
def _plot_scores(results, methods, method_colours, score_type, use_same_x_limit=True):
  score_traces = []
  success_traces = []
  K_vals = sorted(pd.unique(results['K']))
  N = len(K_vals)
  M_sorted = list(reversed(plotter.sort_methods(methods)))
  M_happy = {M: plotter.HAPPY_METHOD_NAMES.get(M, M) for M in M_sorted}

  for kidx, K in enumerate(K_vals):
    K_rows = [row for idx, row in results.iterrows() if row['K'] == K]
    missing_fracs = {M: len([row for row in K_rows if row[M] == MISSING]) / len(K_rows) for M in M_sorted}
    points = {M: [row[M] for row in K_rows if row[M] != MISSING] for M in M_sorted}
    runids = {M: [row['runid'] for row in K_rows if row[M] != MISSING] for M in M_sorted}

    score_traces.append([{
      'type': 'box',
      'boxmean': False,
      'x': points[M],
      'text': runids[M],
      'name': M_happy[M],
      'marker_color': plotter.format_colour(method_colours[M]),
      'orientation': 'h',
      'width': 0.8,
      # Hack: only display the legend for the first trace. Otherwise, it will
      # be duplicated for each trace. This assumes that the methods on each
      # plot and their corresponding colours are invariant; if this is
      # violated, the legend will be wrong.
      'showlegend': kidx == 0,
    } for M in M_sorted])
    success_traces.append({
      'type': 'bar',
      'x': [1 - missing_fracs[M] for M in M_sorted],
      'y': [M_happy[M] for M in M_sorted],
      'marker': {
        'color': [plotter.format_colour(method_colours[M], 0.5) for M in M_sorted],
        'line': {
          'width': 2,
          'color': [plotter.format_colour(method_colours[M]) for M in M_sorted],
        },
      },
      'orientation': 'h',
      'showlegend': False,
    })

  fig = plotly.subplots.make_subplots(
    rows=N,
    cols=2,
    column_widths=[0.2, 0.8],
    shared_xaxes = True,
    shared_yaxes = True,
    row_titles = ['%s subclones' % K for K in K_vals],
    horizontal_spacing = 0.03,
    vertical_spacing = 0.03,
  )
  for idx, (st, ft) in enumerate(zip(score_traces, success_traces)):
    fig.add_trace(ft, col=1, row=idx+1)
    for T in st:
      fig.add_trace(T, col=2, row=idx+1)
  fig.update_xaxes(range=(1, 0), col=1)

  # Whiskers run from `d1` (lower) to `d2` (higher).
  max_x = np.array([max([calc_violin_stats(T['x'])['q2'] for T in st if len(T['x']) > 0]) for st in score_traces])
  min_x = np.array([min([np.min(T['x']) for T in st if len(T['x']) > 0]) for st in score_traces])
  if use_same_x_limit:
    max_x[:] = np.max(max_x)
    min_x[:] = np.min(min_x)
  for idx, (A, B) in enumerate(zip(min_x, max_x)):
    assert B >= A
    rng = B - A
    fig.update_xaxes(
      range=(A - 0.05*rng, B + 0.05*rng),
      col=2,
      row=idx+1
    )

  fig.update_xaxes(
    title_text='Success rate',
    row=N,
    col=1,
  )
  fig.update_xaxes(
    tickformat='.0%',
    col=1,
  )
  fig.update_xaxes(
    zeroline=True,
    zerolinewidth=1,
    zerolinecolor='rgba(0,0,0,0.3)',
    col=2,
  )
  fig.update_xaxes(
    title_text = AXIS_TITLES[score_type]['all_scores'],
    row = N,
    col = 2,
  )

  fig.update_layout(showlegend=True, legend={'traceorder': 'reversed'})
  return fig