Detect Heatwaves and Cold-Spells

The different methods of defining and detecting extreme events, known as heatwaves or cold-spells in both air and water temperature data are encompassed within this package. These detection algorithms may be used on non-temperature data as well however, this is not catered for explicitly here as no use of this technique in the literature currently exists.

CRAN_Status_Badge Travis build status Coverage status JOSS DOI

The heatwaveR package is a project-wide update to the RmarineHeatWaves package, which is itself a translation of the original Python code written by Eric C. J. Oliver. The heatwaveR package also uses the same naming conventions for objects, columns, and arguments as the Python code.

The heatwaveR R package contains the original functions from the RmarineHeatWaves package that calculate and display marine heatwaves (MHWs) according to the definition of Hobday et al. (2016) as well as calculating and visualising marine cold-spells (MCSs) as first introduced in Schlegel et al. (2017a). It also contains the functionality to calculate the categories of MHWs as outlined in Hobday et al. (2018).

This package does what RmarineHeatWaves does, but faster. The entire package has been deconstructed and modularised, and slow portions of the code are being implemented in C++. C++ has already replaced some of the bottlenecks that slowed down the climatology creation portions of the code, and we will slowly but surely improve the efficiency and speed in other portions of the code too. Currently the R code runs about as fast as the original python functions, at least in as far as applying it to single time series of temperatures. Readers familiar with both languages will know about the ongoing debate around the relative speed of the two languages. In our experience, R can be as fast as python, provided that attention is paid to finding ways to reduce the computational inefficiencies that stem from i) the liberal use of complex and inefficient non-atomic data structures, such as data frames; ii) the reliance on non-vectorised calculations such as loops; and iii) lazy (but convenient) coding that comes from drawing too heavily on the tidyverse suite of packages. We will continue to ensure that heatwaveR becomes more-and-more efficient so that it can be applied to large gridded data products with ease.

This new package was developed and released in order to better accommodate the inclusion of the definitions of atmospheric heatwaves in addition to MHWs. Additionally, heatwaveR also provides the first implementation of a definition for a ‘compound heatwave’. There are currently multiple different definitions for this type of event and each of which has arguments provided for it within the ts2clm() and detect_event() functions.

This package may be installed from CRAN by typing the following command into the console:


Or the development version may be installed from GitHub with:


The functions

Function Description
ts2clm() Constructs seasonal and threshold climatologies as per the definition of Hobday et al. (2016).
detect_event() The main function which detects the events as per the definition of Hobday et al. (2016).
block_average() Calculates annual means for event metrics.
category() Applies event categories to the output of detect_event() based on Hobday et al. (in review).
exceedance() A function similar to detect_event() but that detects consecutive days above/below a given static threshold.
event_line() Creates a line plot of heatwaves or cold-spells.
lolli_plot() Creates a timeline of selected event metrics.
geom_flame() Creates flame polygons of heatwaves or cold-spells.
geom_lolli() Creates a lolliplot timeline of selected event metric.

The package also provides data of observed SST records for three historical MHWs: the 2011 Western Australia event, the 2012 Northwest Atlantic event and the 2003 Mediterranean event.

The heatwave metrics

The function will return a list of two tibbles (see the ‘tidyverse’), clim and event, which are the climatology and MHW (or MCS) events, respectively. The climatology contains the full time series of daily temperatures, as well as the the seasonal climatology, the threshold and various aspects of the events that were detected. The software was designed for detecting extreme thermal events, and the units specified below reflect that intended purpose. However, the various other kinds of extreme events may be detected according to the ‘marine heatwave’ specifications, and if that is the case, the appropriate units need to be determined by the user.

Climatology metric Description
doy Julian day (day-of-year). For non-leap years it runs 1…59 and 61…366, while leap years run 1…366. This column will be named differently if another name was specified to the doy argument.
t The date of the temperature measurement. This column will be named differently if another name was specified to the x argument.
temp If the software was used for the purpose for which it was designed, seawater temperature [deg. C] on the specified date will be returned. This column will of course be named differently if another kind of measurement was specified to the y argument.
seas Climatological seasonal cycle [deg. C].
thresh Seasonally varying threshold (e.g., 90th percentile) [deg. C].
var Seasonally varying variance (standard deviation) [deg. C].
threshCriterion Boolean indicating if temp exceeds thresh.
durationCriterion Boolean indicating whether periods of consecutive threshCriterion are >= minDuration.
event Boolean indicating if all criteria that define a MHW or MCS are met.
event_no A sequential number indicating the ID and order of occurrence of the MHWs or MCSs.

The events are summarised using a range of event metrics:

Event metric Description
event_no A sequential number indicating the ID and order of the events.
index_start Start index of event.
index_peak Peak index of event.
index_end Index of event peak.
duration Duration of event [days].
date_start Start date of event [date].
date_peak Date of event peak [date].
date_end End date of event [date].
intensity_mean Mean intensity [deg. C].
intensity_max Maximum (peak) intensity [deg. C].
intensity_var Intensity variability (standard deviation) [deg. C].
intensity_cumulative Cumulative intensity [deg. C x days].
rate_onset Onset rate of event [deg. C / day].
rate_decline Decline rate of event [deg. C / day].

intensity_max_relThresh, intensity_mean_relThresh, intensity_var_relThresh, and intensity_cumulative_relThresh are as above except relative to the threshold (e.g., 90th percentile) rather than the seasonal climatology.

intensity_max_abs, intensity_mean_abs, intensity_var_abs, and intensity_cumulative_abs are as above except as absolute magnitudes rather than relative to the seasonal climatology or threshold.

Note that rate_onset and rate_decline will return NA when the event begins/ends on the first/last day of the time series. This may be particularly evident when the function is applied to large gridded data sets. Although the other metrics do not contain any errors and provide sensible values, please take this into account in the interpretation of the output.


For detailed explanations and walkthroughs on the use of the heatwaveR package please click on the articles tab above, or follow the links below:

Contributing to heatwaveR

To contribute to the package please follow the guidelines here.

Please use this link to report any bugs found.


Hobday, A.J. et al. (2016). A hierarchical approach to defining marine heatwaves, Progress in Oceanography, 141, pp. 227-238.

Schlegel, R. W., Oliver, E. C. J., Wernberg, T. W., Smit, A. J. (2017a). Nearshore and offshore co-occurrences of marine heatwaves and cold-spells. Progress in Oceanography, 151, pp. 189-205.

Schlegel, R. W., Oliver, E. C., Perkins-Kirkpatrick, S., Kruger, A., Smit, A. J. (2017b). Predominant atmospheric and oceanic patterns during coastal marine heatwaves. Frontiers in Marine Science, 4, 323.

Hobday, A. J., Oliver, E. C. J., Sen Gupta, A., Benthuysen, J. A., Burrows, M. T., Donat, M. G., Holbrook, N. J., Moore, P. J., Thomsen, M. S., Wernberg, T., Smale, D. A. (2018). Categorizing and naming marine heatwaves. Oceanography 31(2).


The Python code was written by Eric C. J. Oliver.

Contributors to the Marine Heatwaves definition and its numerical implementation include Alistair J. Hobday, Lisa V. Alexander, Sarah E. Perkins, Dan A. Smale, Sandra C. Straub, Jessica Benthuysen, Michael T. Burrows, Markus G. Donat, Ming Feng, Neil J. Holbrook, Pippa J. Moore, Hillary A. Scannell, Alex Sen Gupta, and Thomas Wernberg.

The translation from Python to R was done by A. J. Smit and the graphing functions were contributed to by Robert. W. Schlegel.


Robert W. Schlegel Department for Biodiversity & Conservation Biology, University of the Western Cape Private Bag X17, Bellville 7535, South Africa E-mail: [email protected]


heatwaveR 0.3.6 (2019-01-16)

  • Finished Alternative Thresholds (Complex Climatologies) vignette
  • Bumbed code coverage back up to 100%
  • AN important potential backwards compatibility breaking change is that by default ts2clm() and exceedance() will no longer produce a var column
    • The argument var = TRUE may be given to produce this column
  • Submitted v0.3.6 to CRAN

heatwaveR (2019-01-15)

  • Began editing Alternative (Complex) Climatology vignette
  • Changed the default argument for exceedance(maxPadLength) from 3 to FALSE to match the new default for ts2clm()
  • Changed the default behaviour of event_line() to no longer require the user to provide start_date and end_date arguments

heatwaveR (2019-01-03)

  • Corrected some typos in the gridded event detection vignette

heatwaveR (2019-01-02)

  • First update of 2019
  • Added 'protoEvents' argument to detect_events.R() for returning the proto events rather than a table for the event metrics

heatwaveR (2018-12-26)

  • Boxing day update

heatwaveR (2018-12-21)

  • Updated text for the OISST preparation vignette
  • Updated text for the gridded event detection vignette

heatwaveR (2018-12-19)

  • Updated text on the landing page to better reflect the updates that have been made over the past few months
  • Fixed typo in event_line() output
  • Updated text for the detection and visualisation vignette
  • Updated text for the exceedance vignette
  • Updated text for the categories vignette
  • Updated text for the OISST preparation vignette

heatwaveR (2018-12-18)

  • Changed time series checking behaviour of exceedance() so that it is the same as ts2clm()

heatwaveR (2018-12-12)

  • Fixed bug in event_line() that caused it to graph events outside of the spread range
  • Expanded testing back up to 100%

heatwaveR (2018-12-06)

  • Fixed bug caused by R not liking dates older than 1970-01-01
  • Changed maxPadLength behaviour in ts2clm() to match the Python default settings

heatwaveR (2018-12-05)

  • Added 'duration_max' to block_average() output
  • Resumed correct version numbering

heatwaveR 0.3.5 (2018-12-03)

  • Increased functionality of block_average()

heatwaveR 0.3.5 (2018-11-01)

  • Updated one figure in a vignette

heatwaveR 0.3.5 (2018-10-26)

  • clim_calc() reinstated to allow for calculation of clims with missing data
  • var calculations reinstated for documentation issues

heatwaveR 0.3.5 (2018-10-20)

  • ts2clm() no longer calls clim_calc(), but clim_calc_cpp() only
  • smooth_percentile() no longer provides option to create variance climatology (the need to no longer create var seemed to not be fully implemented in 0.3.4)

heatwaveR 0.3.4 (2018-10-19)

  • ts2clm() no longer calculates variance column by default
  • make_whole() has been deprecated in favour of make_whole_fast()

heatwaveR 0.3.4 (2018-10-17)

  • All major functions now produce results only up to the fourth decimal place

heatwaveR 0.3.4 (2018-10-16)

  • Clarified some information on the basic detection vignette
  • Corrected a link that went to the wrong page

heatwaveR 0.3.4 (2018-10-03)

  • Changed error handling in proto_event() to return no events than to stop message with an error.
  • This change was picked up by detect_event() without any required changes
  • category() required a bit of cajoling to also output a blank dataframe

heatwaveR 0.3.4 (2018-10-01)

  • Minor tweak to make_whole_fast() to provide a cleaner internal output

heatwaveR 0.3.4 (2018-09-28)

  • Removed several unnecessary columns from category climatology output

heatwaveR 0.3.4 (2018-09-27)

  • Fixed bug in ts2clm() that prevented calculation of clims with large contiguous missing periods of data (e.g. ice coverage).
  • Added argument to category() that allows one to have the function also output the day-to-day (long) category values, rather than just the summary (wide) output.
  • Added lon/lat values to documentation for built-in time series

heatwaveR 0.3.3 (2018-08-23)

  • Added CITATION file so that package citation is now set to JOSS article

heatwaveR 0.3.3 (2018-07-31)

  • Added Zenodo DOI badge
  • JOSS review process complete
  • Added JOSS DOI badge

heatwaveR 0.3.3 (2018-07-25)

  • BUG FIX: corrected issue with clim_calc_cpp not being able to calculate clims from baselines not beginning and ending on the Julian year by making clim_spread plug the gaps beforehand with row-wise means.
  • Rebuilt pkgdown site to reflect version increase
  • v0.3.3 submitted to CRAN

heatwaveR 0.3.2 (2018-07-23)

  • Edits suggested through JOSS review

heatwaveR 0.3.2 (2018-07-12)

  • Remove unneeded copies of data from functions to improve memory-use efficiency.

heatwaveR 0.3.1 (2018-07-10)

  • BUG FIX: corrected issue with make_whole_fast which did not create a whole, complete time series (i.e. missing dates were still present); the missing dates caused clim_calc_cpp to fail

heatwaveR 0.3.0 (2018-06-22)

  • Re-submitted to CRAN in anticipation of ggplot2 changes
  • proto_event now handles all event calculations 'in house'
  • This allows detect_event to now be given a theoretically limitless number of thresholds

heatwaveR (2018-06-08)

  • Logic catch for lolli_plot being asked to highlight more events than are present
  • New vignette that looks at calculating more complex climatologies

heatwaveR (2018-06-07)

  • Tweak to ts2clm

heatwaveR (2018-06-05)

  • Tweaks to detect_event and exceedance

heatwaveR (2018-06-02)

  • Unused Rcpp code removed from master branch
  • Logo changed slightly
  • Codecov back up to 100%
  • Addressed one testthat issue that was causing the OSX CRAN build to fail
  • Added CRAN link to pkgdown site
  • Added Bug Report link to pkgdown site

heatwaveR 0.2.7 (2018-05-30)

  • Accepted on CRAN

heatwaveR 0.2.7 (2018-05-28)

  • Submitted to CRAN

heatwaveR (2018-05-25)

  • Fixes to make_whole and testing
  • Fixes to block_average
  • No longer exporting make_whole and make_whole_fast
  • No longer uses zoo for time series NA handling--made custom function to replace it
  • Additional speed improvements
  • Repair testthat tests

heatwaveR (2018-05-24)

  • Moved all vignettes relating to the upcoming MHW_detection paper to that repo
  • This helps to unclutter this repo as it should be primarily kept for package content

heatwaveR (2018-05-23)

  • Added vignette that shows how tweaking arguments for detect changes the outputs between languages and how those outputs may differ
  • Changed output of detect_event to better match Python version
  • Corrections to testthat to match changes to detect_event output

heatwaveR (2018-05-22)

  • Added C++ function, clim_calc_ccp() for faster climatology calculations; speed of climatology calculation comes down from 50.6 ms in R to 3.4 ms in C++ on my MacBook Pro (15-inch, 2017) 2.9 GHz Intel Core i7 16 GB RAM computer

heatwaveR (2018-05-21)

  • Updated testthat for lolli_plot() and event_line()
  • Updated testthat for ts2clm()
  • Updated testthat for detect_event()

heatwaveR (2018-05-17)

  • Take advantage of C++ speed enhancement in smooth_percentile() by using RcppRoll
  • Update testthat accordingly

heatwaveR (2018-05-17)

  • Basic R vs Python vignette finished

heatwaveR (2018-05-16)

  • Minor fix to testthat
  • codecov up to 100%
  • Fix to geom_lolli() n argument
  • Fix to lolli_plot() y-axis range
  • Minor fix to make_whole()
  • Skeleton of R vs Python vignette added

heatwaveR (2018-05-16)

  • Major speed-up in the climatology creation function. clim_spread() now returns a matrix, not a data frame. This makes the loop in clim_calc() much faster. In testing with the sst_WA data, it leads to a 3.7 fold speed improvement (520 ms down to 140 ms).
  • Speed-up of make_whole() (60 ms down to 40 ms)

heatwaveR (2018-05-15)

  • Removed all instances of detect() in favour of the new pipeline
  • Updated exceedance() to utilise the internal functions
  • Updated object names in block_average()

heatwaveR (2018-05-15)

  • Micro edits to documentation
  • Testing for all exported and internal functions brought up to speed
  • Ensuring that new ts2clm() and detect_event() pipeline returns the same results as the old make_whole() and detect() pipeline

heatwaveR (2018-05-14)

  • Phasing in identical names as in the python version
  • detect_event() now passing checks
  • Must still test for MCSs
  • The old detect() function was unpacked and simplified. Internal code is now in new functions, most of which will not be seen by the user. They are make_whole() proto_event(), clim_calc(), smooth_percentile(), clim_spread(), and ts2clm()
  • ts2clm() used instead of detect_clim()
  • Climatologies can now be calculated independently of the detect functionality
  • exceedance() function testthat checks updated to account for change in variable naming

heatwaveR (2018-05-11)

  • detect() has now been broken into detect_clim() and detect_event()
  • These now also rely on internal functions
  • The purpose of this is to create a family of functions that provide different options
  • New vignette on making short climatologies.

heatwaveR (2018-05-10)

  • One may now provide alternative baselines and climatologies to detect()

heatwaveR (2018-05-05)

  • Testing for category()
  • Testing for block_average()
  • Testing for detect()
  • Testing exceedance()
  • Removed default threshold for exceedance()
  • Tweaks to exceedance() error messages
  • Testing for event_line()
  • Testing for lolli_plot()
  • Tweaks to lolli_plot() error messages

heatwaveR (2018-05-04)

  • New category() function returns the category results for events
  • Still requires testing and improved event naming scheme

heatwaveR (2018-05-03)

  • Minor touch up to examples in geoms.R
  • First draft of heatwaveR hex logo added to site
  • Added category option to event_line()
  • Simplifications and consistency checks to detect()
  • Some writing on Baselines and climatology vignette

heatwaveR (2018-05-02)

  • Fix to event_line() not plotting MCSs correctly
  • Fix error with smooth_percentile and smooth_percentile_width descriptions that were interchanged in detect()
  • Simplify initial lines of leap year calculations (remove redundant code)
  • change from raster::quantile() to stats::quantile()

heatwaveR (2018-04-29)

  • Add option to use a custom baseline to detect() as requested by Maxime Marin (), The University of Tasmania (IMAS) – CSIRO (O&A), and which is present in the python version of the package

heatwaveR (2018-04-28)

  • Remove restriction to require full years for start/end points of climatology calculations in detect()
  • Documentation updated accordingly
  • Vignette on OISST data processing added

heatwaveR (2018-04-26)

  • Removed rlang dependency
  • Touch-up to block_average()
  • Tested make_whole()
  • Basic testing for other functions

heatwaveR (2018-04-25)

  • Established theme for changelog
  • Synced ganalytics
  • Fixed event_line() to acknowledge column names other than t and temp
  • Fixed lolli_plot() to use underlying geom_lolli()
  • Search bar now live
  • Removed all but one use of plyr code

heatwaveR (2018-04-24)

  • Added a file to track changes to the package.
  • Cloned RmarineHeatWaves package to this repo
  • First build of pkgdown site live

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


0.3.6 by Robert W. Schlegel, 2 months ago,

Report a bug at

Browse source code at

Authors: Robert W. Schlegel [aut, cre, ctb] , Albertus J. Smit [aut, ctb]

Documentation:   PDF Manual  

MIT + file LICENSE license

Imports tibble, lubridate, dplyr, stats, utils, zoo, grid, RcppRoll

Depends on data.table, ggplot2

Suggests tidyverse, ggpubr, testthat, knitr, rmarkdown, covr, rerddap, ncdf4, weathercan

Linking to Rcpp, RcppArmadillo

See at CRAN