Having Contractions!

One of the major advantages of having environmental control on our microscopes at the CCI, is that you can get cells to behave a little more like they do in an animal or plant. A great example of this is when looking at cardiomyocytes that can spontaneously start to contract when grown in culture. You can see a load of these on YouTube.

These types of culture are a great model with which to study the effect of drugs or other treatments on the cells of the heart. This post will look at one way to quantify contractile motion without the need for exogenous stains or dyes (which can themselves perturb physiological behaviour).

Measuring contractions

There are really two useful metrics when dealing with cardiomyocytes: the magnitude (how far the cells contract) and frequency of contraction (how many contractions per unit of time). Let’s take these one at a time:

1) Magnitude of contraction

First things first, find a contracting cell. Once that’s done, draw a line selection along the axis of contraction in one of your frames. The dataset has 2 dimensions of spatial intensity data (in x and y) and one of time:

2015-06-Contractions01We can plot the intensity along the selection in a single timepoint (using Fiji, run [Analyze > Plot Profile] also available as Ctrl + k). Here you now have one spatial dimension versus intensity but are lacking the time dimension.


Here’s where the magic happens. If we plot a kymograph, we effectively plot time as a spatial dimension (imagine this as a representation of the plot above in time). We do this by drawing a line selection (as above) and running [Image > Stacks > Reslice].

2015-06-Contractions03In this way, it’s really easy to see the repetitive motion over time. Remember, what we want to measure is the shift in the spatial (in this case X) axis. In order to do this, we go back to plotting a profile.

To do this, draw a line selection horizontally through the image in the rested position (top line below). Plot the profile (Ctrl + k) then just using the down-arrow key, move the selection vertically until you’re overlapping the contracted position. It’s really important to keep the horizontal alignment so that we can compare graphs afterwards. 2015-06-Contractions04Once you have the profiles you can then fit a Gaussian curve to the profile (using Fiji as described in an earlier post or your favourite curve fitting program), and find the mean of the two positions. Note that because we didn’t change the horizontal position, we can compare the plots on the same scale:2015-06-Contractions05Repeating this analysis for several of the contractions in your movie will enhance the accuracy of your measurement. Of course this is the magnitude of contraction for one cell. For more robust analysis, you will need to repeat this process for more cells in the same and other fields.

 2) Frequency of contraction

We can use basically the same technique to look at the frequency of contractions. Instead of making a profile in the spatial dimension though, we use the temporal dimension:

2015-06-Contractions06To analyse the temporal frequency of the signal I’ve once again chosen MATLAB for my data analysis. When plotted using…

plot( frameNum, intensity );

…the original data from the profile should look something like this:


You can use the function findpeaks to calculate the local maxima in the signal:

[peakInt, peakFrames] = findpeaks( intensity, 'minpeakheight', mean(intensity) );

Here I’m using the mean intensity value as a minimum peak height to prevent the identification of peaks in the basal noise (see for example two small peaks at around Frame 60 with intensity of ~31500 counts).

If multiple pseudo-peaks are found in the data, you can always use the ‘threshold’ keyword to specify a local threshold for peak identification. Once you have the right parameters, you can validate the peak identification using the following code to overlay the found peaks with the original data:

plot( peakFrames, peakInt, 'rv', 'MarkerFaceColor', [1 0 0] );

2015-06-Contractions10More importantly, you can calculate the mean difference between the peaks with:

mean( diff( peakFrames ) )

Note that as findpeaks doesn’t take an X-dimension you may need to multiply this by your temporal calibration to get an interval in time (cf. frame) units. In this case, the above function returns a value of 13.5 frames. If the movie was taken at 30 frames per second, that means that the mean interval is 450ms ( = 13.5 / 30 ). Taking the reciprocal of this value gives you the frequency, which is equal to 2.2Hz (= 1 / 0.45 ).

NOTE: I’m using MATLAB 2013a. In later versions of MATLAB, the parameters for findpeaks has been changed. Make sure to check the documentation for your version.


So there you have it. Magnitude and frequency calculated without the use of extraneous dyes. It’s worth pointing out that a much more rigorous (and automated) analysis is possible if you can fluorescently label your cells, as this allows for better morphological analysis. Once I can get my hands on some sample data I’ll make that into another post.

Finally, thanks go to Jon Cox and Michael Griffiths at the Liverpool Institute of Infection and Global Health, for bringing me such an interesting problem!


Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.