예제 #1
0
def plot_situation(tracks, n_tracks=6*3, n_dcs=50, tcz_volume=0.524e9/400,
    min_distance=0, min_distance_std=200/10, zoom=1, t_detail=None, save=False,
    context='notebook'):
    """Plot some T cell tracks, DC positions and T cell zone volume"""
    sns.set(style='ticks', context=context)

    _ = plt.figure(figsize=(8, 5.5))
    gs = gridspec.GridSpec(2,3)
    space_ax = plt.subplot(gs[:,:-1], projection='3d')
    time_ax = plt.subplot(gs[0,-1])
    reach_ax = plt.subplot(gs[1,-1])
    plt.locator_params(nbins=6)

    space_ax.set_title('{} T Cell Tracks & {} DCs'.format(n_tracks, n_dcs))

    n_conditions = len(tracks['Condition'].unique())
    palette = itertools.cycle(sns.color_palette())

    if min_distance_std != 0:
        moved_tracks = tracks.copy()
        for id in tracks['Track_ID'].unique():
            moved_tracks.loc[moved_tracks['Track_ID'] == id, ['X', 'Y', 'Z']] += \
                np.random.randn(3)*min_distance_std
    else:
        moved_tracks = tracks

    for i, (cond, cond_tracks) in enumerate(moved_tracks.groupby('Condition')):
        choice = np.random.choice(cond_tracks['Track_ID'].unique(),
            n_tracks/n_conditions)
        chosen_tracks = cond_tracks[cond_tracks['Track_ID'].isin(choice)]
        for _, track in chosen_tracks.groupby(track_identifiers(chosen_tracks)):
            if t_detail:
                track = track[track['Time'] <= t_detail*60]
            if n_conditions > 1:
                color = sns.color_palette(n_colors=i+1)[-1]
            else:
                color = next(palette)
            space_ax.plot(track['X'].values, track['Y'].values, track['Z'].values,
                color=color)

    tcz_radius = (3*tcz_volume/(4*np.pi))**(1/3)
    ratio = (min_distance/tcz_radius)**3
    r = tcz_radius*(ratio + (1 - ratio)*np.random.rand(n_dcs))**(1/3)
    theta = np.random.rand(n_dcs)*2*np.pi
    phi = np.arccos(2*np.random.rand(n_dcs) - 1)
    dcs = pd.DataFrame({
        'X': r*np.sin(theta)*np.sin(phi),
        'Y': r*np.cos(theta)*np.sin(phi),
        'Z': r*np.cos(phi)})
    space_ax.scatter(dcs['X'], dcs['Y'], dcs['Z'], c='y')

    r = (3*tcz_volume/(4*np.pi))**(1/3)
    for i in ['x', 'y', 'z']:
        circle = Circle((0, 0), r, fill=False, linewidth=2)
        space_ax.add_patch(circle)
        art3d.pathpatch_2d_to_3d(circle, z=0, zdir=i)

    time_ax.set_xlabel('Time within Lymph Node [h]')
    time_ax.set_ylabel('Probab. Density')

    reach_ax.set_xlabel(r'Maximal Reach [$\mu$m]')
    reach_ax.set_ylabel('Probab. Density')

    def residence_time(track): return track['Time'].diff().mean()/60*len(
        track[np.linalg.norm(track[['X', 'Y', 'Z']], axis=1) < r])

    for i, (cond, cond_tracks) in enumerate(moved_tracks.groupby('Condition')):
        color = sns.color_palette(n_colors=i+1)[-1]
        residence_times = [residence_time(track)
            for _, track in cond_tracks.groupby('Track_ID')]
        if not all(time == residence_times[0] for time in residence_times):
            sns.distplot(residence_times, kde=False, norm_hist=True, ax=time_ax,
                label=cond, color=color)
        max_reaches = [max(np.linalg.norm(track[['X', 'Y', 'Z']], axis=1))
            for _, track in cond_tracks.groupby('Track_ID')]
        sns.distplot(max_reaches, kde=False, norm_hist=True, ax=reach_ax,
            label=cond, color=color)

    time_ax.set_yticks([])
    time_ax.axvline(np.median(residence_times), c='0', ls=':')
    sns.despine(ax=time_ax)
    reach_ax.set_yticks([])
    reach_ax.legend()
    reach_ax.axvline(tcz_radius, c='0', ls=':')
    sns.despine(ax=reach_ax)
    equalize_axis3d(space_ax, zoom)
    plt.tight_layout()

    if save == True:
        save = 'situation.png'

    if save:
        plt.savefig(save, dpi=300)
    else:
        plt.show()
예제 #2
0
def plot_tracks(raw_tracks, summary=None, draw_turns=True, n_tracks=25,
    condition='Condition', context='notebook', save=False):
    """Plot tracks"""
    tracks = raw_tracks.copy()
    _uniquize_tracks(tracks)

    if type(summary) == pd.core.frame.DataFrame:
        skip_steps = int(next(word
            for column in summary.columns
            for word in column.split() if word.isdigit()))

    if summary is not None and draw_turns:
        alpha = 0.33
    else:
        alpha = 1

    if condition not in tracks.columns:
        tracks[condition] = 'Default'
    n_conditions = len(tracks[condition].unique())

    sns.set(style='ticks', context=context)
    fig = plt.figure(figsize=(12,12))
    if 'Z' in tracks.columns:
        ax = fig.add_subplot(111, projection='3d')
    else:
        ax = fig.add_subplot(111, aspect='equal')
    labels = []
    for i, (cond, cond_tracks) in enumerate(tracks.groupby(condition)):
        if summary is not None and draw_turns:
            cond_summary = summary[summary[condition] == cond]
            max_turn_column = next(column for column in summary.columns
                if column.startswith('Max. Turn'))
            if len(cond_tracks['Track_ID'].unique()) > n_tracks/n_conditions:
                choice = cond_summary.sort_values(max_turn_column, ascending=False)\
                    ['Track_ID'][:int(n_tracks/n_conditions)]
                cond_tracks = cond_tracks[cond_tracks['Track_ID'].isin(choice)]
        elif len(cond_tracks['Track_ID'].unique()) > n_tracks/n_conditions:
            choice = np.random.choice(cond_tracks['Track_ID'].unique(),
                n_tracks/n_conditions, replace=False)
            cond_tracks = cond_tracks[cond_tracks['Track_ID'].isin(choice)]

        color = sns.color_palette(n_colors=i+1)[-1]
        for j, (_, track) in enumerate(cond_tracks.groupby(track_identifiers(cond_tracks))):
            labels.append(cond)
            track_id = track['Track_ID'].iloc[0]
            if 'Z' in tracks.columns:
                ax.plot(track['X'].values, track['Y'].values, track['Z'].values,
                    color=color, alpha=alpha, label=track_id, picker=5)
            else:
                ax.plot(track['X'].values, track['Y'].values,
                    color=color, alpha=alpha, label=track_id, picker=5)
            if summary is not None and draw_turns:
                turn_time = cond_summary[cond_summary['Track_ID'] == track_id]['Turn Time']
                turn_loc = track.index.get_loc(
                    track[np.isclose(track['Time'], turn_time.values[0])].index.values[0])
                turn_times = track['Time'][turn_loc - 1:turn_loc + skip_steps]
                turn = track[track['Time'].isin(turn_times)]
                if 'Z' in tracks.columns:
                    ax.plot(turn['X'].values, turn['Y'].values, turn['Z'].values,
                        color=color)
                else:
                    ax.plot(turn['X'].values, turn['Y'].values, color=color)

    def on_pick(event):
        track_id = event.artist.get_label()
        if summary is not None:
            print(summary[summary['Track_ID'] == float(track_id)]
                [['Track_ID', 'Condition', 'Mean Velocity', 'Track Duration']])
        else:
            print('Track_ID: ' + track_id)

    fig.canvas.mpl_connect('pick_event', on_pick)

    if 'Z' in tracks.columns:
        equalize_axis3d(ax)
    else:
        sns.despine()
    handles, _ = ax.get_legend_handles_labels()
    unique_entries = OrderedDict(zip(labels, handles))
    ax.legend(unique_entries.values(), unique_entries.keys())
    plt.tight_layout()

    if save:
        conditions = [cond.replace('= ', '')
            for cond in tracks[condition].unique()]
        plt.savefig('Tracks' + '-'.join(conditions) + '.png', dpi=300)
    else:
        plt.show()