2026-09-16

Introduction

  • In 1885, Francis Galton conducted a study in which the height and gender of parents and their offsprings were collected.
  • This data became the basis of his Regression Towards Mediocrity in Hereditary Stature which served as the foundation of the concept of “regression towards the mean”.
  • This presentation uses the data from Galton’s study to explore bivariate normal distributions, the mean, variance, and correlation coefficient as well as plotting the distribution of the parent’s heights using ggplot and plotly libraries.

Bivariate Normal Distribution Definition

Since the study contains the height data from both biological parents, and assuming that the height of the parent is a continous random variable that follows a normal distribution, the joint probability density function can be modeled by the bivariate normal distributions.

\[ P(x_1, x_2) = \frac{1}{2\pi\sigma_1\sigma_2\sqrt{1-\rho^2}} \exp\left[-\frac{z}{2(1-\rho^2)}\right] \]

where

\[ z \equiv \frac{(x_1-\mu_1)^2}{\sigma_1^2} - \frac{2\rho(x_1-\mu_1)(x_2-\mu_2)}{\sigma_1\sigma_2} + \frac{(x_2-\mu_2)^2}{\sigma_2^2} \]

Bivariate Normal Distribution Components

To calculate the bivariate normal distributions, the mean, variance, covariance, and correlation coefficient are needed.

The mean and variance: \[ \mu = \frac{1}{n}\sum_{i=1}^{n} x_i \qquad \qquad \sigma^2 = \frac{1}{n}\sum_{i=1}^{n} (x_i - \mu)^2 \] The covarriance and correlation coefficient: \[ V_{12} = \frac{1}{n}\sum_{i=1}^{n} (x_{1i} - \mu_1)(x_{2i} - \mu_2) \qquad \qquad \rho = \frac{V_{12}}{\sigma_1\sigma_2} \]

Exploring the Dataset

This is a brief overview of the dataset.

##   father mother childHeight gender
## 1   78.5   67.0        73.2   male
## 2   78.5   67.0        69.2 female
## 3   78.5   67.0        69.0 female
## 4   78.5   67.0        69.0 female
## 5   75.5   66.5        73.5   male
## 6   75.5   66.5        72.5   male
  • father: Height of the father (inches)
  • mother: Height of the mother (inches)
  • childHeight: Height of the adult child (inches)
  • gender: Gender of the adult child

Distribution of Parent’s Heights

The parent’s height can be displayed using a histogram using ggplot. It is evident from the histograms that the heights appear normally distributed.

Scatter Plot of Parent’s Heights

The parent’s heights can be displayed as a scatter plot using ggplot. From the plot, it is somewhat evident that there are some regions that are denser than others.

Contour Plot of Parent’s Height

Using plotly, it is easier to see the density of the heights. The 2D kernel density of the points needs to be calculated before plotting using the kde2d function from the MASS library.

Kernel Density Surface of Parent’s Height

Using the same density as the previous slide, the joint density of the parents heights can be displayed using plotly.

Code Used to Generate the Density Surface

dens <- kde2d(GaltonFamilies$father, GaltonFamilies$mother, n = 50)
plot_ly(x = dens$x, y = dens$y, z = dens$z) %>%
  add_surface() %>%
  layout(
    title = "Density Surface of Parent's Height",
    scene = list(
      xaxis = list(title = "Father's Height"),
      yaxis = list(title = "Mother's Height"),
      zaxis = list(title = "Density")
    )
  )

Mean, Variance, Covariance, and Correlation of Parent’s Heights

Here is a summary of the mean, variance, covariance, and correlation coefficient. They will be used to calculate the bivariate normal distributions for this dataset.

##   mean_father mean_mother var_father var_mother    cov_fm     cor_fm
## 1    69.19711    64.08929    6.13295    5.24816 0.3424771 0.06036612

Code for Bivariate Normal Distribution of Parent’s Heights

# calculate the inputs
mu1  <- mean(GaltonFamilies$father)
mu2  <- mean(GaltonFamilies$mother)
sig1 <- sd(GaltonFamilies$father)
sig2 <- sd(GaltonFamilies$mother)
rho  <- cor(GaltonFamilies$father, GaltonFamilies$mother)
# define the bivariate_normal
bivariate_normal <- function(x1, x2, mu1, mu2, sig1, sig2, rho) {
  z <- ((x1 - mu1)^2 / sig1^2) -
       (2 * rho * (x1 - mu1) * (x2 - mu2)) / (sig1 * sig2) +
       ((x2 - mu2)^2 / sig2^2)
  (1 / (2 * pi * sig1 * sig2 * sqrt(1 - rho^2))) *
    exp(-z / (2 * (1 - rho^2)))
}

Plot of Bivariate Normal Distribution of Parent’s Heights

Comparison of the Density and Bivariate Normal Distribution

Note how the bivariate normal distribution appears to be a good approximation of the density function for the heights.

Conclusion

Validity of Bivariate Normal Distribution

While the plots and calculations here do not suffice to provide a measurable delta between the kernel density (KD) and the bivariate normal distributions (BN), they are enough to show that the BN approximates the KD for this dataset.

Power of ggplot and plotly

Both ggplot and plotly are very powerful plotting packages in R. They each have their strengths and weaknesses. ggplot provides very useful syntax and included functions (the density could’ve been calculated as part of the graph) while plotly provides powerful interactive plots.