The birds and the butterflies

Nov 29, 2017

The latest instalment of Rhiannon Dalrymple’s latitudinally-sprawling work has just landed in Ecological Monographs (pdf). It’s truly epic, and explores a suite of hypotheses regarding life’s colourful diversity.

Animal color phenotypes are invariably influenced by both their biotic community and the abiotic environments. A host of hypotheses have been proposed for how variables such as solar radiation, habitat shadiness, primary productivity, temperature, rainfall and community diversity might affect animal color traits. However, while individual factors have been linked to coloration in specific contexts, little is known about which factors are most important across broad taxonomic and geographic scales. Using data collected from 570 species of birds and 424 species of butterflies from Australia which inhabit an area spanning a latitudinal range of 35 degrees and covering deserts, tropical and temperate forests, savannas and heathlands, we test multiple hypotheses from the coloration literature and assess their relative importance. We show that bird and butterfly species exhibit more reflective and less saturated colors in better-lit environments, a pattern that is robust across an array of variables expected to influence the intensity or quality of ambient light in an environment. Both taxa display more diverse colors in regions with greater net primary production and longer growing seasons. Models that included variables related to energy inputs and resources in ecosystems have better explanatory power for bird and butterfly coloration overall than do models that included community diversity metrics. However, the diversity of the bird community in an environment was the single most powerful predictor of color pattern variation in both birds and butterflies. We observed strong similarities across taxa in the covariance between color and environmental factors, suggesting the presence of fundamental macro-ecological drivers of visual appearance across disparate taxa.

. . . . . . .

Pavo 1.3.0

Sep 20, 2017

Version 1.3 of pavo is on its way through CRAN, so be sure to update in the next day or two. It’s a serious update! So serious that we rolled through two increments before we actually got it out.

Big changes include a handful of new functions to make life easier, like sensdata() for easily retrieving pavo's internal data, and the addition of the CIELCh model (the cylindrical transformation of CIELab), accessible via colspace(). Rafael has done some amazing work by adding in noise-corrected colorspaces, as well totally rewriting the 3d plots (tetrachromatic and CIELab) for far better control and aesthetics.


  • jnd2xyz() converts distances (in JND, resulting from a coldist() call) into cartesian coordinates
  • plot() methods for objects resulting from jnd2xyz()
  • jndrot() produces rotations of Cartesian coordinates resulting from jnd2xyz()
  • coldist2mat() converts coldist() result from a pairwise data.frame to a distance matrix
  • sensdata() function for retrieving and/or visualising pavo’s in-build spectral data


  • tetraplot() and cieplot() have been completely rewritten to allow finer viewing control
  • tetraplot() allows forced perspective using size to denote distance
  • voloverlap() and vol() have also been changed to work with the new tetraplot() options
  • getspec() has been rewritten to be faster, more general, and allow parallel processing
  • subset functions now allow more than one argument to be used, and allow further attributes to be passed onto grep (e.g. invert = TRUE)


  • fixed bug in coldist() on log-transformation when object was neither of class vismodel nor colspace
  • fixed bug in dL calculation when input is a colspace object
  • fixed bug in vismodel() when a data frame, matrix or rspec object was passed as the background
  • fixed bug in colspace() models when using non-standard receptor names or ordering
  • fixed bug in hexagon() model when calculating location & metrics for achromatic stimuli
  • fixed location of red vertex in tetraplot()
  • fixed bug in the argument names for expanding text labels in colspace plots
  • removed na.rm argument from aggspec() that was causing a bug when the error function did not have that argument. User should pass it as an argument to the function if necessary.
  • changed default to achro=FALSE in coldist()
  • replaced the modelled receptor sensitivities of the honeybee Apis melifera with the empirical sensitivities from Peitsch et al (1992)
  • the built-in ‘green’ background spectrum is no longer normalized
  • removed wavelength limitations in the calculation of H3 from summary.rspec
  • all visual systems (except CIE) have been normalized to have an integral of 1

. . . . . . .

New preprint on methods for comparing colour samples

Aug 19, 2017

Rafael Maia and I have a new preprint out, which deals with some common statistical and methodological issues that arise when comparing groups of colours. Viewer-subjective “colour spaces” are a common tool for studying colour traits, and the underlying analytical objective typically centres on estimating how similar or dissimilar samples of colours are to a given viewer (e.g. How effective is this cryptic colouration? Are these species sexually dichromatic? How conspicuous are these warning colours?).

There are numerous methods for doing so, but they often rely on shaky implicit assumptions. We use a simulation-based approach to test the efficacy of the more popular approaches, and show that most aren’t quite up to the job. We argue that an explicit analytical distinction should be drawn between estimating the statistical presence and the perceptual magnitude of group differences in colour space, and suggest some (hopefully) useful ways of achieving each. Out preferred solutions are currently being woven into pavo as the paper makes its way through review, and we’d of course be happy to hear any thoughts in the interim.

. . . . . . .

New paper on lure polymorphism

Aug 17, 2017

Our latest paper—and the last from my PhD (phew)— on deceptive colour polymorphism is out in BMC Evolutionary Biology. It’s an experimental test of the idea, fleshed out in an earlier paper, that the ‘white’ and ‘yellow’ morphs of the spiny spider G. fornicata may essentially represent alternate strategies for standing out amidst the visual noise of their forest habitats. We find partial support across a handful of experiments, with prey learning (I used only colour-naive flies) being an obvious axis of variation that remains to be explored.

. . . . . . .

Comment on spider colouration

Aug 01, 2017

I recently had the opportunity to provide comment on a neat paper on deceptive spider colouration for The New Scientist — the resulting write-up can be found in their news section.

. . . . . . .

Pavo 1.1

May 06, 2017

Version 1.1 of pavo is currently working its way through the internals of CRAN, and should be available over the next day or two. It mostly fixes some bugs following the 1.0 release, and also rolls the segment analysis into the new colspace() framework, with a new plot of its own.


  • segspace() replaces the deprecated segclass(), and is accessed via the colspace() argument space = ‘segment’. The results of segspace() are also now compatible with coldist() for the estimation of Euclidean colour-distances.
  • segplot() is a plot for Endler’s (1990) segment analysis, and is accessed — along with all other 2d plots — via plot.colspace()


  • the use of relative quantum catches is now optional in the categorical colorspace (though still produces a warning), for greater flexibility
  • updated several functions to work when rspec object has only one spectrum
  • fixed bug in voloverlap where interactive plots would result in error
  • fixed incorrect labels in the maxwell triangle plot
  • fixed a bug in as.rspec() in which lim was not applied when interpolate = FALSE
  • fixed bug in aggplot() which resulted in error when using lty, lwd arguments
  • warning if ocular media is being used in both vismodel() and sensmodel()
  • added an ‘all’ option to the achromatic argument in vismodel()
  • added the ability to calculate dL for cielab models in coldist()
  • added some more informative messages and warnings

As always, feel free to get in touch with any issues or suggestions.

. . . . . . .