soft-matter / trackpy-examples

sample images, examples, and speed tests for trackpy
Other
21 stars 42 forks source link

d.plot returning particles and drift? #21

Closed Jumpet closed 9 years ago

Jumpet commented 9 years ago

Hello (again), I talked to @tacaswell yesterday about an error I kept getting,

I am having trouble with the drift. I thought it was something specific to the data I was running but I used the sample data of the 300 frames in water and got the same result pictured below

image

I think it is plotting the drift and the next set of trajectories together? code ran is here below

-- coding: utf-8 --

""" Created on Mon May 11 00:11:46 2015

@author: Zach


import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rc('figure',  figsize=(10, 6))
mpl.rc('image', cmap='gray')

import numpy as np
import pandas as pd
from pandas import DataFrame, Series  # for convenience

import pims
import trackpy as tp

def convert_to_gray(frame):
    "Very simple (not necessarily optimal) grayscale conversion"
    return frame[:, :, 0]  # take the red channel

frames = pims.ImageSequence('C:/Users/Zach/Desktop/bulk_water/*.png', process_func=convert_to_gray)
f = tp.locate(frames[0], 11, invert=True)
print tp.annotate(f, frames[0])

ax = f['mass'].hist()
ax.set(xlabel='mass', ylabel='count')

f = tp.locate(frames[0], 11, invert=True, minmass=2000)
tp.annotate(f, frames[0])

f = tp.batch(frames[:100], 11, minmass=2000, invert=True)
t = tp.link_df(f, 5, memory=3)

t1 = tp.filter_stubs(t, 50)
print 'Before:', t['particle'].nunique()
print 'After:', t1['particle'].nunique()

tp.mass_size(t1.groupby('particle').mean()) 

condition = lambda x: (x['mass'].mean() > 2800) & (x['size'].mean() < 3.0) & (x['ecc'].mean() < 0.1)
t2 = tp.filter(t1, condition) 

tp.annotate(t2[t2['frame'] == 0], frames[0])

tp.plot_traj(t1)

d = tp.compute_drift(t1)
d.plot()
tm = tp.subtract_drift(t1, d)
tp.plot_traj(tm)

im = tp.imsd(tm, 100/285., 24)
im.plot(loglog=True, style='k-', alpha=0.1, legend=False)  # black lines, semitransparent, no legend
plt.gca().set_ylabel(r'$\langle \Delta r^2 \rangle$ [$\mu$m$^2$]'); 

em = tp.emsd(tm, 100/285., 24)

ax = em.plot(loglog=True, style='o')
ax.set(ylabel=r'$\langle \Delta r^2 \rangle$ [$\mu$m$^2$]', xlabel='lag time $t$')
ax.set(ylim=(1e-2, 10))

em.plot(loglog=True, style='ro')
tp.utils.fit_powerlaw(em)

removing d.plot() on line 53 of this returns a trajectory plots with and without drift (or as far as I can tell two different sets of trajectories) I could not reproduce the plot of the x and y drift shown in the walk through Am I overlooking something simple with this code?

[TAC added markup]

tacaswell commented 9 years ago

use triple back ticks '`' to mark code blocks (not normal single quotes, on most US keyboards this is under the ~ to the left of 1).

tacaswell commented 9 years ago

I suspect you just need to explicitly make new figures in a couple of places.

Jumpet commented 9 years ago

HI, I'm still pretty new to python and I've been trying a few different things to get d.plot to its own figure, but to no avail. How should be creating the new figure?

tacaswell commented 9 years ago

fig = plt.figure() is the simplest way.

If you are just learning python I would suggest avoiding using the pandas plotting, it is bad habits you don't need to develop, and just use matplotlib directly.

Jumpet commented 9 years ago

hmm I came across something like I moved on because I couldn't figure out how to implement it.... I know it doesn't take arguments.... (right?)

fig = plt.figure() d = tp.compute_drift(t1) d.plot()

is this in the ballpark of anything?

danielballan commented 9 years ago

I have found pandas plotting to be unreliable, especially when "reusing" axes with more than one command.

My usual approach is:

fig, ax = plt.subplots()
d = tp.compute_drift(t1)
d.plot(ax=ax)
# then do whatever you want with ax, such as ax.set(ylabel='drift')
Jumpet commented 9 years ago

I've been doing some more wrestling with the sample data... Using the approach from @danielballan the plot for the drift comes out clear! (first 50 frames) image

however I haven't been able to get the tm plot to come out right ... following drift is image

code segment i've been changing around.. tp.annotate(t2[t2['frame'] == 0], frames[0])

tp.plot_traj(t1)

fig, ax = plt.subplots() d1 = tp.compute_drift(t1) d1.plot(ax=ax)

d = tp.compute_drift(t1) d.plot()

tm = tp.subtract_drift(t1, d) tp.plot_traj(tm)

how do return that second trajectory plot to the just the trajectories?/why is it plotting drift on it as well? deleting d.plot() didn't solve the issue this time around

danielballan commented 9 years ago

It is reusing axes. Make new axes

fig, ax = plt.subplots()

and pass them explicitly.

tp.plot_traj(tm, ax=ax)

On Mon, May 11, 2015 at 1:45 PM Jumpet notifications@github.com wrote:

I've been doing some more wrestling with the sample data... Using the approach from @danielballan https://github.com/danielballan the plot for the drift comes out clear! (first 50 frames) [image: image] https://cloud.githubusercontent.com/assets/12387456/7571113/618e9676-f7e3-11e4-9c59-f044f6eed499.png

however I haven't been able to get the tm plot to come out right ... following drift is [image: image] https://cloud.githubusercontent.com/assets/12387456/7571142/8a9d4b52-f7e3-11e4-8fc0-61f452e85361.png

code segment i've been changing around..

tp.annotate(t2[t2['frame'] == 0], frames[0])

tp.plot_traj(t1)

fig, ax = plt.subplots() d1 = tp.compute_drift(t1) d1.plot(ax=ax)

d = tp.compute_drift(t1) d.plot()

tm = tp.subtract_drift(t1, d) tp.plot_traj(tm)

how do return that second trajectory plot to the just the trajectories?/why is it plotting drift on it as well? deleting d.plot() didn't solve the issue this time around

— Reply to this email directly or view it on GitHub https://github.com/soft-matter/trackpy-examples/issues/21#issuecomment-100993461 .

Jumpet commented 9 years ago

Looks like the figures are plotting correctly now! However, the tm and t1 look very similar... this is returning tm as t1 without drift right?

tp.plot_traj(t1)

fig, ax = plt.subplots() d1 = tp.compute_drift(t1) d1.plot(ax=ax)

d = tp.compute_drift(t1) tm = tp.subtract_drift(t1, d)

fig, ax = plt.subplots() tp.plot_traj(tm, ax=ax)

A separate question... I am trying to implement this code on images I have from a fluorescent scope.... however the image is mostly green. how do you modify the code you used to change the color of the water sample... def convert_to_gray(frame): "Very simple (not necessarily optimal) grayscale conversion" return frame[:, :, 0] # take the red channel to take the green channel in this image? blue captured005 mostly still_0001

Jumpet commented 9 years ago

Found another work around for the green image.. I think it is appropriate to close this now