This notebook is part of a tutorial series for the FRETBursts burst analysis software.
In this notebook we present a typical FRETBursts workflow for us-ALEX smFRET burst analysis. Briefly, we show how to perform background estimation, burst search, burst selection, FRET histograms, ALEX histograms, sub-population selection and FRET efficiency fit.
We start loading FRETBursts
and printing the citation info:
from fretbursts import *
- Optimized (cython) burst search loaded. - Optimized (cython) photon counting loaded. ------------------------------------------------------------- You are running FRETBursts (version 0.4rc4-20-g4ea8dd4). If you use this software in a publication, please cite it as: FRETBursts - An opensource single-molecule FRET burst analysis toolkit. A. Ingargiola 2014. https://github.com/tritemio/FRETBursts -------------------------------------------------------------
Please remember to always cite* FRETBursts in publications or presentations.*
Note that FRETBursts version string tells you the exact revision that is currently in use (we use versioneer). Storing the version in the notebook helps reproducibility and in tracking software regressions.
The following cell imports some libraries and setup the plot style:
import os
%matplotlib inline
import fretbursts.style
The full list of smFRET measurements used in the FRETBursts tutorials can be found on Figshare.
Here we download the us-ALEX data-file and put it in a folder named data
, inside the notebook folder.
For this purpose we use the download_file
function provided by FRETBursts:
url = 'http://files.figshare.com/1839121/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5'
download_file(url, save_dir='./data')
URL: http://files.figshare.com/1839121/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5 File: 0023uLRpitc_NTP_20dT_0.5GndCl.hdf5 File already on disk: C:\Data\Antonio\software\src\fretbursts_notebooks\notebooks\data/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5 Delete it to re-download.
Let's select now a data-file. We can either paste the filename in a variable, or we can use a GUI Open-File dialog. In either cases we'll end up with the a file-name stored in the variable full_fname
.
We can select a data file with an "Open File" windows (note: it may pop-up in the foreground):
#full_fname = gui_fname('./')
#full_fname
Now full_fname
contains the path of the file you just selected. Run again the previous cell to select a new file.
Alternatively, we can directly define the file name to be loaded:
# That's an example dataset, download it from (link here)
file_name = "0023uLRpitc_NTP_20dT_0.5GndCl.hdf5"
# Here the folder is the subfolder "data" of current notebook folder
folder_name = './data/'
and concatenate the data folder with the file name:
full_fname = folder_name + file_name
full_fname
'./data/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5'
Let's check that the file exists:
if os.path.isfile(full_fname):
print "Perfect, I found the file!"
else:
print "Sorry, I can't find the file:\n", full_fname
Perfect, I found the file!
We can finally load the measurement and store it in a variable called (go figure) d
.
For convenience we also set the correction coefficients so that they will be used in the subsequent analysis. The correction coefficients are:
leakage
dir_ex
(ALEX-only)gamma
d = loader.hdf5(fname=full_fname)
d.add(leakage=0.11, dir_ex=0.04, gamma=1.)
NOTE: at any later moment after burst search we can modify these coefficient using the
Data
methodsupdate_leakage
,update_dir_ex
andupdate_gamma
respectively. Using these methods all the burst data will be updated.
At this point, in d
, we only have the timestamps (ph_times_t
) and the detector numbers (det_t
):
d.ph_times_t, d.det_t
(array([ 146847, 188045, 294124, ..., 47999470676, 47999545211, 47999580470], dtype=int64), array([0, 1, 1, ..., 1, 1, 0], dtype=uint8))
We need to define some ALEX parameters:
det_donor_accept
)alex_period
)D_ON
and A_ON
)d.add(det_donor_accept=(0, 1), alex_period=4000, D_ON=(2850, 580), A_ON=(900, 2580))
We have to check the consistency of the alternation histogram to verify whether the parameters are correct:
bpl.plot_alternation_hist(d)
The previous alternation histogram looks correct, so we can apply the current parameters:
loader.usalex_apply_period(d)
#donor: 727351 #acceptor: 1579957
data_0023uLRpitc_NTP_20dT_0.5GndCl G1.000
If the previous histogram does not look right, you can go back and modify the parameters in the d.add(...)
cell and re-plot the histogram until it looks fine. Don't forget to apply the parameters with loader.usalex_apply_period(d)
as a last step.
NOTE: After applying the ALEX parameters a new array of timestamps containing only photons inside the excitation periods is created (name
d.ph_times_m
). To save memory, by default, the old timestamps array (d.ph_times_t
) is deleted. Therefore, in the following, when we talk about all-photon selection we always refer to all photons inside the excitation periods.
The entire measurement data is now in the variable d
. Printing it will give a compact representation containing the file-name and some eventual parameters (only the $\gamma$-factor in this case):
d
data_0023uLRpitc_NTP_20dT_0.5GndCl G1.000
To check the measurement duration run:
d.time_max()
599.99475587500001
As a first step of the analysis we need to estimate the background. The assumption is that the background is a Poisson process and therefore the photon waiting times are exponentially distributed. Since the background can change during the measurement a new estimation is computed every time_s
seconds (this time is called the background period).
A problem is that in the photon waiting times distribution we have both signal and background. Therefore we need to choose a threshold to discriminate between the exponential tail from the rest.
Choosing a threshold and fitting the exponential tail are two different problems. FRETBursts provides several ways to specify the minimum threshold and different functions to fit the exponential tail.
You can find more info in the documentation for calc_bg()
method,
the background
module
and exp_fitting
module.
Let start with a standard Maximum Likelihood (ML) background fit with a minimum tail threshold of 500us:
d.calc_bg(bg.exp_fit, time_s=1000, tail_min_us=500)
- Calculating BG rates ... [DONE]
We can look how the fit looks with:
dplot(d, hist_bg, show_fit=True)
<matplotlib.axes._subplots.AxesSubplot at 0x16570470>
Optionally, we can specify a threshold for each channel to obtain a better fit:
d.calc_bg(bg.exp_fit, time_s=1000, tail_min_us=(800, 4000, 1500, 1000, 3000))
- Calculating BG rates ... [DONE]
dplot(d, hist_bg, show_fit=True)
<matplotlib.axes._subplots.AxesSubplot at 0x19e0f4e0>
Finally, is possible to let FRETBursts infer the threshold automatically with:
d.calc_bg(bg.exp_fit, time_s=1000, tail_min_us='auto', F_bg=1.7)
- Calculating BG rates ... [DONE]
this is the recommended approach.
dplot(d, hist_bg, show_fit=True)
<matplotlib.axes._subplots.AxesSubplot at 0x1694eb38>
The background rates are stored in Data()
attributes bg
, bg_dd
, bg_ad
, bg_aa
. These contain all the fitted background rates for each channel and period.
We can also get the average background for each channel:
d.rate_m, d.rate_dd, d.rate_ad, d.rate_da, d.rate_aa
([2263.083665751471], [592.99706058743868], [1005.1639974718599], [77.881170869621982], [589.59903565452544])
First step of burst analysis is the burst search.
We'll use the sliding-window algorithm on all photons. Note that all-photons here means all the photons selected in the alternation histogram. An important variation compared to the classical sliding-windows is that the threshold-rate for burst start is computed as a function of the background and it changes when the background changes during the measurement.
Let perfom a burst search evaluating the photon rate with 10 photons (m=10
), and selecting a minimum rate 6 times the background rate (F=6) on all photons (default):
d.burst_search(L=10, m=10, F=6)
- Performing burst search (verbose=False) ...[DONE] - Calculating burst periods ...[DONE] - Counting D and A ph and calculating FRET ... - Applying background correction. - Applying leakage correction. - Applying direct excitation correction. [DONE Counting D/A]
The previous command perfoms the burst search, corrects the bursts sizes for background and spectral leakage,
applies the gamma correction and compute FRET and Stoichiometry. See the
burst_search
documentation for more details.
We can plot the resulting FRET histogram like this:
dplot(d, hist_fret);
All the pre-defined plots follow this pattern:
call the generic dplot()
function, passing 2 parameters:
d
in this case)hist_fret
)In some case we can add other optional parameters to tweak the plot.
All the plot functions start with hist_
for histograms, scatter_
for scatter-plots or timetrace_
for plots function of measurement time. You can use autocompletion to find all the plot function or you can look in bursts_plot.py
where all the plot functions are defined.
Instead of hist_fret
we can use hist_fret_kde
to add a KDE overlay. Also, we can plot a weighted histogram by passing an additional parameter weights
:
dplot(d, hist_fret, show_kde=True);
dplot(d, hist_fret, show_kde=True, weights='size');
- Overwriting the old E_fitter object with the new weights.
You can experiment with different weighting schema (for all supported weights see get_weigths()
function in fret_fit.py
).
When performing the burst search we specified L=10
without explaining what it is. L is traditionally the minimum size (number of photons) for a burst: smaller bursts will be rejected. By setting L=m (10 in this case) we are deciding to don't discard any burst (because the smallest detected burst has at least m counts).
Selecting the bursts in a second step considering the corrected burst size, results in a more accurate an un-biased selection.
For example we can select bursts with more than 30 photons (after background, gamma and leakage corrections) and store the result in a new Data()
variable ds
:
ds = Sel(d, select_bursts.size, th1=30)
By defaults the burst size includes donor and acceptor photons during donor excitation. To also add acceptor photons during acceptor excitation (naa
) we can pass add_naa=True
:
ds = Sel(d, select_bursts.size, add_naa=True, th1=30)
Similar to the plot functions, all the selection functions are defined in select_bursts.py
and you can access them typing select_bursts.
and using TAB for autocompletion.
See also:
- Burst selection in the documentation.
In particular the function
select_bursts.size
andSel
.
Let's replot the FRET histogram after selection (note that now we are passing ds
that contains the selected bursts):
dplot(ds, hist_fret);
Note how the histogram is much more defined after the burst selection.
Under the hood the previous hist_fret
plot creates a MultiFitter
object for $E$ values. This object, stored as ds.E_fitter
, operates on multi-channel data and computes the histogram, KDE and can fit the histogram with a model (lmfit.Model).
Now, as just an example, we fit the histogram with 3 Gaussian peaks, using the already created ds.E_fitter
object:
ds.E_fitter.fit_histogram(mfit.factory_three_gaussians())
- Adding parameter "p1_fwhm" - Adding parameter "p2_fwhm" - Adding parameter "p3_fwhm"
dplot(ds, hist_fret, show_model=True)
<matplotlib.axes._subplots.AxesSubplot at 0x1cb649e8>
The bin width can be changed with binwidth
argument or the full bins can be passed in bins
(overriding binwidth
).
We can customize the appearance of this plot (type hist_fret?
for the complete set of arguments).
For example to change from a bar plot to a line-plot we use the hist_style
argument:
dplot(ds, hist_fret, show_model=True, hist_style='line')
<matplotlib.axes._subplots.AxesSubplot at 0x1c8a2c50>
We can customize the line-plot, bar-plot, the model plot and the KDE plot by passing dictionaries with matplotlib style. The name of the arguments are:
hist_plot_style
: style fot the histogram line-plothist_bar_style
: style for the histogram bar-plotmodel_plot_style
: style for the model plotkde_plot_style
: style for the KDE plotLet see an example:
dplot(ds, hist_fret, show_model=True, hist_style='bar', show_kde=True,
kde_plot_style = dict(linewidth=5, color='orange', alpha=0.6),
hist_plot_style = dict(linewidth=3, markersize=8, color='b', alpha=0.6))
plt.legend()
<matplotlib.legend.Legend at 0x1a624048>
Similarly we can plot the burst size using all photons (type hist_size?
for all the plot options):
dplot(ds, hist_size, add_naa=True);
Or plot the burst size histogram for the different components:
dplot(ds, hist_size_all);
NOTE: The previous plot may generate a benign warning due to the presence of zeroes when switching to log scale. Just ignore it.
A scatterplot Size vs FRET:
dplot(ds, scatter_fret_nd_na)
xlim(-1, 2)
(-1, 2)
We can further select only bursts smaller than 300 photons to get rid of eventual aggregates:
ds2 = Sel(ds, select_bursts.size, th2=300)
and superimpose the two histograms before and after selection to see the difference:
ax = dplot(ds2, hist_fret, hist_style='bar', show_kde=True,
hist_bar_style = dict(facecolor='r', alpha=0.5, label='Hist. no large bursts'),
kde_plot_style = dict(lw=3, color='m', label='KDE no large bursts'))
dplot(ds, hist_fret, ax=ax, hist_style='bar', show_kde=True,
hist_bar_style = dict(label='Hist. with large bursts'),
kde_plot_style = dict(lw=3, label='KDE with large bursts'))
plt.legend();
We can find the KDE peak position in a range (let say 0.2 ... 0.6):
ds.E_fitter.find_kde_max(np.r_[0:1:0.0002], xmin=0.2, xmax=0.6)
and plot it with show_kde_peak=True
, we also use show_fit_value=True
to show a box with the fitted value:
dplot(ds, hist_fret, hist_style='line',
show_fit_value=True,
show_kde=True, show_kde_peak=True);
Instead of using the KDE, we can use the peak position as fitted from a gaussian model.
ds.E_fitter.fit_histogram(mfit.factory_three_gaussians())
- Adding parameter "p1_fwhm" - Adding parameter "p2_fwhm" - Adding parameter "p3_fwhm"
To select which peak to show we use fit_from='p1_center'
:
dplot(ds, hist_fret, hist_style='line',
show_fit_value=True, fit_from='p1_center',
show_model=True);
The string 'p1_center'
is the name of the parameter of the gaussian fit that we want to show in the text box. To see all the parameters of the models we look in:
ds.E_fitter.params
p3_amplitude | p2_center | p3_center | p1_sigma | p1_center | p2_amplitude | p2_sigma | p3_sigma | p1_amplitude | |
---|---|---|---|---|---|---|---|---|---|
0 | 0.6282173 | 0.8298785 | 0.3561328 | 0.06488076 | 0.03559297 | 0.236329 | 0.1204 | 0.1790067 | 0.1352828 |
We can make a simple E-S scatter plot with scatter_alex
:
dplot(ds, scatter_alex, figsize=(4,4), mew=1, ms=4, mec='black', color='purple')
<matplotlib.axes._subplots.AxesSubplot at 0x1ccabbe0>
We can also plot the ALEX histogram with a scatterplot overlay using hist2d_alex
:
dplot(ds, hist2d_alex);
We can try get rid of the large donor-only population simply selecting burst with at least 4 photons in the acceptor channel (during acceptor excitation):
ds2 = Sel(ds, select_bursts.naa, th1=4)
dplot(ds2, hist2d_alex);
dplot(ds2, hist_fret);
Much better, but maybe we want to select a region on the E/S histogram to completely eliminate the donor-only.
To select bursts graphically we need to open the ALEX histogram in a new (QT) window, dragg the mouse to define a selection and having it printed here in the notebook.
When you are done you can close the additional window and continue the execution.
Here the commands:
# Switches to open plot in external window
#%matplotlib qt
# ALEX histogram with GUI selection enabled
#dplot(ds, hist2d_alex, gui_sel=True)
# Switch back to show plots inline in the notebook
#%matplotlib inline
Now, to apply the selection, we paste the values obtained from the previous plot. We can use a rectangular or elliptical selection (see image), using select_bursts.ES
and setting respectively rect=True
or rect=False
. Here we use the ellitpical selection:
d_fret_mix = Sel(ds, select_bursts.ES, E1=-0.07, E2=1.17, S1=0.18, S2=0.70, rect=False)
By plotting the FRET histogram we can double check that the selection has been applied:
dplot(d_fret_mix, hist2d_alex)
<matplotlib.axes._subplots.AxesSubplot at 0x20ff1ef0>
Now we can further separate high- and low FRET sub-populations. We can go back to the GUI:
#%matplotlib qt
#dplot(d_fret_mix, hist2d_alex, gui_sel=True)
#%matplotlib inline
d_high_fret = Sel(d_fret_mix, select_bursts.ES_ellips, E1=0.65, E2=1.09, S1=-0.13, S2=0.96)
d_low_fret = Sel(d_fret_mix, select_bursts.ES_ellips, E1=-0.19, E2=0.64, S1=-0.05, S2=0.92)
dplot(d_high_fret, hist2d_alex);
dplot(d_low_fret, hist2d_alex);
We can for example compute the ratio of high- and low-fret bursts:
1.*d_low_fret.num_bursts/d_high_fret.num_bursts
array([ 2.35721108])
To plot a burst-width histogram we can just use hist_width
instead of hist_fret
:
dplot(d_low_fret, hist_width)
<matplotlib.axes._subplots.AxesSubplot at 0x20344b00>
Let use a larger bin size, plots two sub-populations (in different color) and add a legend:
ax = dplot(d_high_fret, hist_width, bins=r_[0:10:0.2], color='g')
dplot(d_low_fret, hist_width, bins=r_[0:10:0.2], ax=ax, color='r')
plt.legend(['High-FRET population', 'Low-FRET population'])
<matplotlib.legend.Legend at 0x1fe87ba8>
Finally we compute the mean burst width for each subpopulation:
mean_b_width_low_fret = bl.b_width(d_low_fret.mburst[0]).mean()*d_low_fret.clk_p*1e3
mean_b_width_high_fret = bl.b_width(d_high_fret.mburst[0]).mean()*d_high_fret.clk_p*1e3
print 'Mean burst width: %.1f ms (high-fret), %.1f (low-fret)' % (mean_b_width_high_fret, mean_b_width_low_fret)
Mean burst width: 2.3 ms (high-fret), 3.0 (low-fret)
We can fit a FRET distribution to any model. For example here we fit the FRET selection (2 FRET sub-population) with 2 gaussians. The model is a Model
object from the lmfit
library.
The first step, previously performed implicitely by the hist_fret()
plot function, is creating a MultiFitter
object for both $E$ and $S$. This is done calling bext.burst_fitter()
. We can compute histogram, KDE and fit the histogram in one single step:
bext.bursts_fitter(d_fret_mix, 'E', binwidth=0.03, bandwidth=0.03, model=mfit.factory_two_gaussians())
bext.bursts_fitter(d_fret_mix, 'S', binwidth=0.03, bandwidth=0.03, model=mfit.factory_gaussian())
<fretbursts.mfit.MultiFitter at 0x217f15f8>
However if we want to modify the model (for example to add a constrain) we may want to perform the fit in a second step. To skip the fitting, we simply avoid passing a model
:
bext.bursts_fitter(d_fret_mix, 'E', binwidth=0.03, bandwidth=0.03)
bext.bursts_fitter(d_fret_mix, 'S', binwidth=0.03, bandwidth=0.03)
<fretbursts.mfit.MultiFitter at 0x1c2ab8d0>
Now we create a model and initialize the parameters using mfit.factory_two_gaussians()
(all the functions mfit.factory_*
return initialized models):
model = mfit.factory_two_gaussians()
We can see the list of parameters, the intial values and bounds by looking in model.params
:
params = model.make_params()
params.values()
[<Parameter 'p1_sigma', 0.03, bounds=[0.01:0.2]>, <Parameter 'p1_center', 0.1, bounds=[-1:2]>, <Parameter 'p1_amplitude', 1, bounds=[0.01:None]>, <Parameter 'p1_fwhm', None, bounds=[None:None], expr='2.3548200*p1_sigma'>, <Parameter 'p2_amplitude', 1, bounds=[0.01:None]>, <Parameter 'p2_sigma', 0.03, bounds=[0.01:0.2]>, <Parameter 'p2_center', 0.9, bounds=[-1:2]>, <Parameter 'p2_fwhm', None, bounds=[None:None], expr='2.3548200*p2_sigma'>]
We can modify some initial values and contrains (bounds):
params['p1_center'].set(0.2, min=-0.1, max=1.1)
params['p2_center'].set(0.8, min=-0.1, max=1.1)
Finally we assign the model and we fit the histogram with one of the supported minimization methods (default is least-squares):
d_fret_mix.E_fitter.fit_histogram(model=model) # The default method is 'leastsq'
#d_fret_mix.E_fitter.fit_histogram(model=model, method='lbfgsb')
#d_fret_mix.E_fitter.fit_histogram(model=model, method='nelder')
#d_fret_mix.E_fitter.fit_histogram(model=model, method='slsqp')
In the early examples we directly passed the model to fit_histogram. Here we first created the model, tweaked some initial values and constrains and then used this model to fit the $E$ histogram.
To plot the model with the fitted parameters on top of the FRET histogram we add show_model=True
as seen before:
dplot(d_fret_mix, hist_fret, show_model=True)
<matplotlib.axes._subplots.AxesSubplot at 0x1c2aa9e8>
The minimizer object returned by lmfit
is saved in the list fit_res
(one element per channel) in the fitter object:
results = d_fret_mix.E_fitter.fit_res[0]
results
<lmfit.model.ModelFit at 0x1fe7a7f0>
For example we can take a look at the initial parameters:
results.init_params.values()
[<Parameter 'p1_fwhm', -inf, bounds=[-inf:inf], expr='2.3548200*p1_sigma'>, <Parameter 'p1_sigma', 0.03, bounds=[0.01:0.2]>, <Parameter 'p1_center', 0.1, bounds=[-1:2]>, <Parameter 'p1_amplitude', 1, bounds=[0.01:inf]>, <Parameter 'p2_amplitude', 1, bounds=[0.01:inf]>, <Parameter 'p2_sigma', 0.03, bounds=[0.01:0.2]>, <Parameter 'p2_center', 0.9, bounds=[-1:2]>, <Parameter 'p2_fwhm', -inf, bounds=[-inf:inf], expr='2.3548200*p2_sigma'>]
and at the fitted parameters:
results.params.values()
[<Parameter 'p1_fwhm', value=0.35848587678986787 +/- 0.0157, bounds=[-inf:inf], expr='2.3548200*p1_sigma'>, <Parameter 'p1_sigma', value=0.15223493803767077 +/- 0.00666, bounds=[0.01:0.2]>, <Parameter 'p1_center', value=0.37645470520418911 +/- 0.00614, bounds=[-1:2]>, <Parameter 'p1_amplitude', value=0.71186025412304077 +/- 0.026, bounds=[0.01:inf]>, <Parameter 'p2_amplitude', value=0.29885179326522859 +/- 0.0234, bounds=[0.01:inf]>, <Parameter 'p2_sigma', value=0.1138702389159689 +/- 0.0096, bounds=[0.01:0.2]>, <Parameter 'p2_center', value=0.81372681680143 +/- 0.00957, bounds=[-1:2]>, <Parameter 'p2_fwhm', value=0.26814391600410187 +/- 0.0226, bounds=[-inf:inf], expr='2.3548200*p2_sigma'>]
Moreover, for convenience, the fitter object (E_fitter
) saves the fitted parameter values in E_fitter.params
(a pandas DataFrame):
d_fret_mix.E_fitter.params
p2_fwhm | p1_center | p2_amplitude | p2_sigma | p1_fwhm | p2_center | p1_sigma | p1_amplitude | |
---|---|---|---|---|---|---|---|---|
0 | 0.2681439 | 0.3764547 | 0.2988518 | 0.1138702 | 0.3584859 | 0.8137268 | 0.1522349 | 0.7118603 |
Lmfit allows to print useful fit reports that include statistics like reduced chi-square, error ranges ($\pm 1 \sigma$) and correlations:
print results.fit_report()
[[Model]] Composite Model: 2-gaussians [[Fit Statistics]] # function evals = 113 # data points = 46 # variables = 6 chi-square = 0.637 reduced chi-square = 0.016 [[Variables]] p1_amplitude: 0.71186025 +/- 0.025965 (3.65%) (init= 1) p1_center: 0.37645470 +/- 0.006136 (1.63%) (init= 0.1) p1_fwhm: 0.35848587 +/- 0.015694 (4.38%) == '2.3548200*p1_sigma' p1_sigma: 0.15223493 +/- 0.006664 (4.38%) (init= 0.03) p2_amplitude: 0.29885179 +/- 0.023411 (7.83%) (init= 1) p2_center: 0.81372681 +/- 0.009569 (1.18%) (init= 0.9) p2_fwhm: 0.26814391 +/- 0.022614 (8.43%) == '2.3548200*p2_sigma' p2_sigma: 0.11387023 +/- 0.009603 (8.43%) (init= 0.03) [[Correlations]] (unreported correlations are < 0.100) C(p1_amplitude, p1_sigma) = 0.764 C(p2_amplitude, p2_sigma) = 0.754 C(p1_sigma, p2_center) = 0.550 C(p1_amplitude, p2_center) = 0.514 C(p1_center, p2_center) = 0.476 C(p1_center, p1_sigma) = 0.413 C(p1_amplitude, p1_center) = 0.398
For more on how to use the powerful lmfit features refer to the lmfit documentation.
For an intial inspection of a data file is common to do a timetrace plot. We also can do a similar plot called ratetrace that does not bin the data but shows the instantaneous rate. In both cases is convenient to scroll the plot interactively.
In FRETBursts we have timetrace and ratetrace plots that support interactive scrolling. We just need to switch from the inline backend to the QT, like we did before.
And here the commands:
#%matplotlib qt
#dplot(ds, ratetrace, scroll=True, bursts=True)
#dplot(ds, timetrace, tmax=600, scroll=True, bursts=True)
#%matplotlib inline
from IPython.core.display import HTML
HTML(open("./styles/custom2.css", "r").read())