I like working with weird and unexpected datasets. And when they don’t come to me - I go get them myself. This week I scraped Wikipedia for the details of every single Playboy’s Playmate of the Month since the first PMOM in January 1954. I am going to share with you how I did this, and then we’re going to look at some very interesting graphs demonstrating the change which the Playboy model’s body went through over the years. It is worth noting that there has been previous work on this subject before, but those researchers only took under consideration the Playmate of the Year in 1960-2000, and reached some very correlative and questionable conclusions.

Is this post NSFW? I think not. I would even go as to say my daughters need to read this, when time comes.

The D is Silent

Wikipedia is fortunately quite well structured, except for a few mishaps here and there. Each year with its (usually1) 12 playmates has its own page, and in it each playmate appears in her own table of class infobox vcard. Not all playmates have all information, for example some appear without their hometown, some without their height. But it should be a very easy task for the rvest package to get everything Wikipedia has on every playmate. Example:

library(tidyverse)
library(rvest)
library(stringr)
library(lubridate)
library(magrittr)

getPlaymates <- function(url) {
  read_file(url) %>%
    gsub(pattern = "<br>|<br />", replacement = "\n", .) %>%
    read_html() %>%
    html_nodes(".infobox") %>%
    html_text() %>%
    str_split("\n")
}

url <- "https://en.wikipedia.org/wiki/List_of_Playboy_Playmates_of_2016"

playmates2016 <- getPlaymates(url)

playmates2016[[1]]
##  [1] "Amberleigh West"                        
##  [2] "Personal details"                       
##  [3] "Born"                                   
##  [4] ""                                       
##  [5] "(1991-09-04) September 4, 1991 (age 25)"
##  [6] ""                                       
##  [7] "Sedro-Woolley, Washington, US"          
##  [8] "Hometown: Mount Vernon, WA"             
##  [9] "Measurements"                           
## [10] "Bust: 32D"                              
## [11] ""                                       
## [12] "Waist: 23"                              
## [13] ""                                       
## [14] "Hips: 32"                               
## [15] "Height"                                 
## [16] "5 ft 6 in (1.68 m)"                     
## [17] "Weight"                                 
## [18] "110 lb (50 kg)"                         
## [19] ""

The getPlaymates function takes a url of a single year, reads in the playmates data and returns a list of string vectors representing each playmate’s data. The only thing left is to find each element of data we’re after, e.g. via extracting regex. That means a lot of stringr and a lot of purrr. For example, let’s extract all heights in centimeters:

extractNumberFromString <- function(s) {
  str_extract_all(s, "[0-9]")[[1]] %>% paste(collapse = "") %>% as.numeric()
}

getHeight <- function(playmate) {
    pattern <- "1[4-9][0-9][\\s]?cm|1\\.[4-9][0-9][\\s]?m"
    measures <- str_extract(playmate, pattern)
    realMeasureInd <- which(!is.na(measures))
    if (length(realMeasureInd) > 0) {
      return(extractNumberFromString(measures[realMeasureInd[1]]))
    } else {
      return(NA)
    }
  }
  
map_dbl(playmates2016, getHeight)
##  [1] 168 170 175 170 173 175 175 180 180 175 175 178

Height is either specified in centimeters (“1XY cm”) or in meters (“1.XY m”). The regex looks for either of those in all strings of a single playmate’s info, making sure we select only heights above 140 cm. Notice getHeight will get you the first expression matching your pattern, so be exact. This is why I insisted on heights above 140cm - otherwise Jayne Mansfield’s height will be her bust size, 102 cm, because it comes before her height, 166 cm! Another function, extractNumberFromString, is used to turn this height string into a number. Lastly, if the function doesn’t find a pattern matching height, it returns NA.

Once you get one function, you get them all:

extractNumberFromString <- function(s) {
  str_extract_all(s, "[0-9]")[[1]] %>% paste(collapse = "") %>% as.numeric()
}

inch2cm <- function(n) {
  floor(grid::convertX(grid::unit(n, "inches"), "cm", valueOnly = TRUE))
}

extractStateFromString <- function(s) {
  str_extract(s, paste0("(", paste(state.name, collapse = "|"), ")"))
}

getURLForYear <- function(year) {
  paste0("https://en.wikipedia.org/wiki/List_of_Playboy_Playmates_of_", year)
}

getPlaymates <- function(url) {
  read_file(url) %>%
    gsub(pattern = "<br>|<br />", replacement = "\n", .) %>%
    read_html() %>%
    html_nodes(".infobox") %>%
    html_text() %>%
    str_split("\n")
}

getName <- function(playmates) {
  map_chr(playmates, `[[`, 1)
}

getBornDate <- function(playmates) {
  f <- function(playmate) {
    if (playmate[1] == "Nicki Thomas") {
      return(as.Date("1954-03-22"))
    }
    bornDates <- str_extract(playmate, "[0-9]{4}-[0-9]{2}-[0-9]{2}")
    realDateInd <- which(!is.na(bornDates))
    if (length(realDateInd) > 0) {
      return(as.Date(bornDates[realDateInd[1]]))
    } else {
      return(NA)
    }
  }
  
  map(playmates, f) %>% unlist %>% as_date()
}

getHeightOrWeight <- function(playmates, height = TRUE) {
  f <- function(playmate, height = TRUE) {
    pattern <- ifelse(height, "1[4-9][0-9][\\s]?cm|1\\.[4-9][0-9][\\s]?m", "[0-9]{2}[\\s]?kg")
    measures <- str_extract(playmate, pattern)
    realMeasureInd <- which(!is.na(measures))
    if (length(realMeasureInd) > 0) {
      return(extractNumberFromString(measures[realMeasureInd[1]]))
    } else {
      return(NA)
    }
  }
  
  map_dbl(playmates, f, height)
}

getState <- function(playmates) {
  f <- function(playmate) {
    #pattern <- paste0("[A-Z][A-Za-z\\s]+,[\\s]?(", paste(state.name, collapse = "|"), ")")
    pattern <- paste0("(", paste(state.name, collapse = "|"), ")")
    states <- str_extract(playmate, pattern)
    realStateInd <- which(!is.na(states))
    if (length(realStateInd) > 0) {
      return(extractStateFromString(states[realStateInd[1]]))
    } else {
      return(NA)
    }
  }
  
  map_chr(playmates, f)
}

getBustWaistHips <- function(playmates, measure) {
  f <- function(playmate, measure) {
    pattern <- paste0(measure, ":\\s[0-9]{2}[\"]?[A-Z]*")
    measures <- str_extract(playmate, pattern)
    realMeasureInd <- which(!is.na(measures))
    if (length(realMeasureInd) > 0) {
      return(inch2cm(extractNumberFromString(measures[realMeasureInd[1]])))
    } else {
      return(NA)
    }
  }
  
  map_dbl(playmates, f, measure)
}

getMonth <- function(year) {
  if (!year %in% c(1954, 1955, 1958, 1970, 2009, 2017)) {
    return(1:12)
  } else {
    yearExp <- paste0("y", year)
    return(
      switch(yearExp,
           "y1954" = c(1:3, 5, 7:12),
           "y1955" = c(1:2, 4:11),
           "y1958" = c(1:9, 10, 10, 11:12),
           "y1970" = c(1:9, 10, 10, 11:12),
           "y2009" = c(1:7, 9:12),
           "y2017" = c(1:7)))
  }
}

getAge <- function(issueDate, bornDate) {
  floor(as.double(difftime(issueDate, bornDate)/365))
}

getBMI <- function(weight, height) {
  weight / ((height/100) ^ 2)
}

And now we use a lot of tidyverse to get all playmates data in a single pipe:

playmates <- tibble(year = 1954:2017) %>%
  mutate(url = map_chr(year, getURLForYear),
         playmates = map(url, getPlaymates),
         name = map(playmates, getName),
         bornDate = map(playmates, getBornDate),
         height = map(playmates, getHeightOrWeight),
         weight = map(playmates, getHeightOrWeight, FALSE),
         state = map(playmates, getState),
         bust = map(playmates, getBustWaistHips, "Bust"),
         waist = map(playmates, getBustWaistHips, "Waist"),
         hips = map(playmates, getBustWaistHips, "Hips"),
         month = map(year, getMonth)) %>%
  unnest(name, bornDate, height, weight, state, bust, waist, hips, month) %>%
  mutate(issueDate = make_date(year, month, 1),
         decade = (year %/% 10) * 10,
         age = getAge(issueDate, bornDate),
         bmi = getBMI(weight, height))

playmates %>% select(year, month, name, age, state, height, weight, bust, waist, hips)
## # A tibble: 760 x 10
##     year month              name   age      state height weight  bust
##    <int> <dbl>             <chr> <dbl>      <chr>  <dbl>  <dbl> <dbl>
##  1  1954     1   Margie Harrison    NA       <NA>    165     NA    NA
##  2  1954     2     Marilyn Waltz    22  Wisconsin    163     51    91
##  3  1954     3 Dolores Del Monte    21 Washington    168     54    86
##  4  1954     5     Joanne Arnold    23       <NA>    165     NA    NA
##  5  1954     7      Neva Gilbert    24   New York    168     59    91
##  6  1954     8     Arline Hunter    22      Idaho    168     54    96
##  7  1954     9    Jackie Rainbow    21       <NA>     NA     NA    NA
##  8  1954    10   Madeline Castle    20       <NA>     NA     NA    NA
##  9  1954    11      Diane Hunter    17 Washington    166     57    86
## 10  1954    12        Terry Ryan    21       <NA>     NA     NA    91
## # ... with 750 more rows, and 2 more variables: waist <dbl>, hips <dbl>

We got 760 months (with 756 models, four models appeared in more than a single month!). You see above the 1954 models, many have missing values - don’t worry, later years data are much more complete.

Plot and Tell

What is happening to playmates’ height?

library(magick)
## Linking to ImageMagick 6.9.9.4
## Enabled features: cairo, freetype, fftw, ghostscript, lcms, pango, rsvg, webp
## Disabled features: fontconfig, x11
library(grid)

logo <- image_read("~/playboy.png")

plotMeasure <- function(measure, .x) {
    minMaxPlaymates <- playmates %>%
      select_("issueDate", "name", measure) %>%
      na.omit() %>%
      arrange_(measure) %>%
      slice(c(1, n())) %>%
      mutate(rank = c(paste("min", measure), paste("max", measure))) %>%
      select_("rank", "issueDate", "name", measure)
    
    p <- ggplot(playmates, aes_string("issueDate", measure)) +
      geom_point() +
      geom_smooth(method = "loess", size = 2) +
      ggtitle(paste("Playmate of the Month:", str_to_title(measure), "over Time")) +
      geom_point(data = minMaxPlaymates, colour="red", size=3) +
      geom_text(data = minMaxPlaymates, aes(label = name), vjust = 1.2) +
      labs(x = "Date", y = str_to_title(measure)) +
      theme_minimal() +
      theme(plot.title = element_text(hjust = 0.5, size = 15))
    
    print(p)
    
    grid.raster(logo, width = 0.06, height = 0.08, x = .x, y = 0.96)
    
    minMaxPlaymates
}

plotMeasure("height", 0.23)

## # A tibble: 2 x 4
##         rank  issueDate          name height
##        <chr>     <date>         <chr>  <dbl>
## 1 min height 1965-04-01  Sue Williams    150
## 2 max height 2000-12-01 Cara Michelle    188

As you can see the playmates height has increased through the years, on average in 4 cm, from a median of 1.66 m in the 1950s (slightly above the US woman average height according to this) to 1.70 m in the 2010s (more like the Dutch woman average height). Notice the plotMeasure function also returns the min and max height playmates: Sue Williams from April 1965 was the shortest playmate reaching 1.50 m, and Cara Michelle from December 2000 was the tallest, with 1.88 m.

So this is a 2.5% increase. Has the playmates weight also increased by 2.5%?

plotMeasure("weight", 0.22)

## # A tibble: 2 x 4
##         rank  issueDate               name weight
##        <chr>     <date>              <chr>  <dbl>
## 1 min weight 1960-11-01        Joni Mattis     39
## 2 max weight 1963-10-01 Christine Williams     68

Nope, it didn’t. The median weight of playmates remained 54 kg, with only a slight decrease during the 1980s. Notice the min and max weight playmates: Joni Mattis from November 1960 weighted 39 kg - sounds a tad anorexic but she was very short as well (1.57 m). And Christine Williams from October 1963 was by far the heaviest playmate at 68 kg but she was also quite tall (1.83 m).

So, what happens when the height increases but the weight remains the same?

plotMeasure("bmi", 0.24)

## # A tibble: 2 x 4
##      rank  issueDate                name      bmi
##     <chr>     <date>               <chr>    <dbl>
## 1 min bmi 2015-08-01      Dominique Jane 15.03558
## 2 max bmi 1964-10-01 Rosemarie Hillcrest 23.38435

That’s right, your BMI decreases. And look at that decrease, reflecting every feminist justful cry out there, about the way women are portrayed in popular culture and specifically in nude or porn magazines. To better demonstrate let’s calculate for every decade the percentage of playmates having BMI below 18, which is considered “Underweight”:

playmates %>% group_by(decade) %>% summarise(underweightProp = mean(bmi < 18, na.rm = TRUE))
## # A tibble: 7 x 2
##   decade underweightProp
##    <dbl>           <dbl>
## 1   1950      0.08571429
## 2   1960      0.07894737
## 3   1970      0.23333333
## 4   1980      0.54237288
## 5   1990      0.39316239
## 6   2000      0.40196078
## 7   2010      0.36764706

During the 1950s and 1960s less than 10% of playmates were “Underweight”, while during the 1980s this rate was over 50%! The only hopeful message I can give here to women, is that it looks like since the 80s the BMI of playmates is on the (slow) rise.

And here I can’t resist showing you the min and max BMI playmates, Rosemary Hillcrest from October 1964 and Dominique Jane from August 2015:

library(jpeg)
library(gridExtra)
rosemary <-  rasterGrob(as.raster(readJPEG("~/playmates/rosemarie_hillcrest.jpg")),
                    width = 0.7, height = 0.7, interpolate = FALSE)
dominique <-  rasterGrob(as.raster(readJPEG("~/playmates/dominique_jane.jpg")),
                    width = 0.7, height = 0.7, interpolate = FALSE)
grid.arrange(rosemary, dominique, ncol = 2)
grid.raster(logo, width = 0.06, height = 0.08, x = 0.21, y = 0.95)
grid.text("Playmates with Max and Min BMI Ever", x = 0.5, y = 0.95,
          just = "center", gp = gpar(fontsize = 15))
grid.text("Rosemary Hillcrest, Oct 1964, BMI 23.3", x = 0.05, y = 0.88,
          just = "left", gp = gpar(fontsize = 13))
grid.text("Dominique Jane, Aug 2015, BMI 15.0", x = 0.55, y = 0.88,
          just = "left", gp = gpar(fontsize = 13))

Not to body-shame Dominique Jane, but in my opinion Rosemary Hillcrest is a more realistic representation of a… well, woman. At a perfectly normal BMI of 23.3 she is curvaceous and healthy. And to think she has the maximum BMI in over 60 years of playmates!

90-60-90

How about Bust, Waist and Hips sizes of playmates through the years?

bustWaistHips <- playmates %>%
  select(issueDate, bust, waist, hips) %>%
  gather(measure, value, -issueDate)

ggplot(bustWaistHips, aes(issueDate, value, color = measure)) +
  geom_point(alpha = 0.5) +
  geom_smooth(method = "loess", size = 1) +
  ggtitle(paste("Playmate of the Month: Bust, Waist and Hips over Time")) +
  labs(x = "Date", y = "Size (cm)") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 15))

grid.raster(logo, width = 0.06, height = 0.08, x = 0.07, y = 0.96)

Nice: The hips size doesn’t seem to be changing, or maybe slightly decreasing. However the bust size is quite strongly decreasing, while the waist size is increasing. This makes sense, assuming the methods of measureing these sizes remained the same through 60 years. The “ideal”2 woman’s breasts have become smaller, and her waist has become larger, maybe reflecting she is fitter and works on her abs more. In women body shape jargon this reflects the transition between admiring “Hourglass” women to “Rectangle” women.

Note I’ve thrown aside here any data regarding bra size, I assume that with the increase in surgical implants of breasts, this factor would moderate the decrease in “overall” bust size.

Interesting to show here the bust-to-waist ratio through the years:

playmates %<>% mutate(bust_to_waist_ratio = bust / waist)

plotMeasure("bust_to_waist_ratio", 0.14)

## # A tibble: 2 x 4
##                      rank  issueDate           name bust_to_waist_ratio
##                     <chr>     <date>          <chr>               <dbl>
## 1 min bust_to_waist_ratio 2007-10-01  Spencer Scott            1.191176
## 2 max bust_to_waist_ratio 1962-09-01 Mickey Winters            2.022222

The bust-to-waist ratio has decreased by 13% from a median of 1.56 in the 1950s (a.k.a “Hourglass”, think Joan of Mad Men), to a median of 1.36 in the 2010s (a.k.a “Rectangle”, think Cameron Diaz). The max bust-to-waist ratio playmate is Micky Winters from February 1962, with a bust size of 91 cm and a waist size of 45 cm. The min bust-to-waist ratio playmate is Spencer Scott from October 2007, a bust of 81 cm and a waist size of 68 cm

The Average Playmate

So let’s get that “Average Playmate” for each decade, by height, weight, bust, waist and hips sizes, and let’s give her the most common name for that decade:

commonNames <- playmates %>%
  mutate(firstName = map_chr(name, function(x) str_split(x, " ")[[1]][1])) %>%
  select(decade, name, firstName) %>%
  dplyr::count(decade, firstName) %>%
  top_n(1) %>%
  select(-n)

meanPlaymates <- playmates %>%
  group_by(decade) %>%
  summarise_each(funs(mean(., na.rm = TRUE)),
                 c(height, weight, bust, waist, hips)) %>%
  mutate_each(funs(round(., digits = 1)),
              c(height, weight, bust, waist, hips))

inner_join(commonNames, meanPlaymates)
## # A tibble: 3 x 7
##   decade firstName height weight  bust waist  hips
##    <dbl>     <chr>  <dbl>  <dbl> <dbl> <dbl> <dbl>
## 1   1960     Nancy  163.9   52.0  91.0  56.7  88.8
## 2   1980     Karen  168.7   51.3  89.2  58.5  86.9
## 3   1990  Jennifer  170.5   52.9  88.1  59.4  87.1

To summarise, in the 1950s and 1960s you would see in Playboy “Marylin” and “Nancy”, with a “Hourglass” shape and a realistic height of ~1.65 m. In the 2000s and 2010s you would see “Nicole” and “Ashley”, with a more “Rectangle” shape, reaching ~1.70 m and skinnier.

To better demonstrate this let’s look at the image of a playmate who has the least “distance” to this “Average Playmate”, in each decade:

getDistToDecadeMean <- function(.decade, height, weight, bust, waist, hips) {
  decadeVec <- meanPlaymates %>%
    filter(decade == .decade) %>%
    select(-decade) %>%
    unlist()
  
  playmateVec <- c(height, weight, bust, waist, hips)
  
  sqrt(sum((decadeVec - playmateVec) ^ 2))
}

playmates %<>%
  mutate(distToDecadeMean = pmap_dbl(list(decade, height, weight, bust, waist, hips),
                                     getDistToDecadeMean))

playmates %>%
  group_by(decade) %>%
  arrange(distToDecadeMean) %>%
  select(decade, name) %>%
  slice(1)
## # A tibble: 7 x 2
## # Groups:   decade [7]
##   decade                name
##    <dbl>               <chr>
## 1   1950       Janet Pilgrim
## 2   1960        Kari Knudsen
## 3   1970 Victoria Cunningham
## 4   1980         Carmen Berg
## 5   1990    Marliece Andrada
## 6   2000      Markéta Jánská
## 7   2010 Elizabeth Ostrander
janet <-  rasterGrob(as.raster(readJPEG("~/playmates/1950s_janet_pilgrim.jpg")),
                     width = 0.8, height = 0.7, interpolate = FALSE, y = 0.37)
kari <-  rasterGrob(as.raster(readJPEG("~/playmates/1960s_kari_knudsen.jpg")),
                    width = 0.8, height = 0.7, interpolate = FALSE, y = 0.37)
victoria <-  rasterGrob(as.raster(readJPEG("~/playmates/1970s_victoria_cunningham.jpg")),
                        width = 0.8, height = 0.7, interpolate = FALSE, y = 0.37)
carmen <-  rasterGrob(as.raster(readJPEG("~/playmates/1980s_carmen_berg.jpg")),
                      width = 0.8, height = 0.7, interpolate = FALSE, y = 0.37)
marelice <-  rasterGrob(as.raster(readJPEG("~/playmates/1990s_marliece_andrada.jpg")),
                        width = 0.8, height = 0.7, interpolate = FALSE)
marketa <-  rasterGrob(as.raster(readJPEG("~/playmates/2000s_marketa_janska.jpg")),
                       width = 0.8, height = 0.7, interpolate = FALSE)
elizabeth <-  rasterGrob(as.raster(readJPEG("~/playmates/2010s_elizabeth_ostrander.jpg")),
                         width = 0.8, height = 0.7, interpolate = FALSE)
grid.arrange(janet, kari, victoria, carmen, marelice, marketa, elizabeth, ncol = 4)
grid.text("Playmates Closest to Average Body In Each Decade", y = 0.95,
          just = "center", gp = gpar(fontsize = 15))
grid.raster(logo, width = 0.06, height = 0.08, x = 0.12, y = 0.95)
grid.text("1950s: Janet Pilgrim", x = 0.02, y = 0.88,
          just = "left", gp = gpar(fontsize = 11))
grid.text("1960s: Kari Knudsen", x = 0.27, y = 0.88,
          just = "left", gp = gpar(fontsize = 11))
grid.text("1970s: Victoria Cunningham", x = 0.50, y = 0.88,
          just = "left", gp = gpar(fontsize = 11))
grid.text("1980s: Carmen Berg", x = 0.78, y = 0.88,
          just = "left", gp = gpar(fontsize = 11))
grid.text("1990s: Marliece Andrada", x = 0.02, y = 0.45,
          just = "left", gp = gpar(fontsize = 11))
grid.text("2000s: Markéta Jánská", x = 0.27, y = 0.45,
          just = "left", gp = gpar(fontsize = 11))
grid.text("2010s: Elizabeth Ostrander", x = 0.52, y = 0.45,
          just = "left", gp = gpar(fontsize = 11))

The Age Of Innocence

Another hopeful message, or maybe it’s simple puritanism, or maybe they’re lying - playmates age seems to be going up:

plotMeasure("age", 0.24)

## # A tibble: 2 x 4
##      rank  issueDate                  name   age
##     <chr>     <date>                 <chr> <dbl>
## 1 min age 1958-01-01 Elizabeth Ann Roberts    16
## 2 max age 1957-08-01        Dolores Donlon    36

The median age in the 1950s for a playmate was 21. In the 2010s it is 24. The youngest playmate ever was Elizabeth Ann Roberts from January 1958, when she was just 16 years old. The oldest was Dolores Donlon from August 1957 - 36 years old at the time. My age. That’s the oldest Playboy lets you get :(

The Origin Of The Bunny

Where do playmates come from in the US?

statesData <- playmates %>%
  count(state) %>%
  rename(region = state, value = n) %>%
  na.omit() %>%
  right_join(tibble(region = c(state.name, "district of columbia"))) %>%
  replace_na(list(value = 0)) %>%
  mutate(region = tolower(region))

choroplethr::state_choropleth(statesData,
                              title = "Where do           US Playmates Come From?",
                              num_colors = 1)

grid.raster(logo, width = 0.06, height = 0.08, x = 0.15, y = 0.84)

statesData %>%
  arrange(-value)
## # A tibble: 51 x 2
##          region value
##           <chr> <dbl>
##  1   california   171
##  2        texas    42
##  3     new york    41
##  4     illinois    39
##  5      florida    32
##  6         ohio    26
##  7   new jersey    19
##  8   washington    18
##  9 pennsylvania    17
## 10    wisconsin    13
## # ... with 41 more rows

La La Land, where else.

But notice that many playmates have NA for state - this is rarely because the playmate’s state isn’t detailed, and more because she simply isn’t from the United States. Many playmates come from Canada and the UK, and you also see France, Poland, Russia and the Czech Republic3. Relying on that, let’s see how many playmates are not from the US, by decade:

playmates %>%
  group_by(decade) %>%
  summarise(nonUS = mean(is.na(state))) %>%
  ggplot(aes(decade, nonUS)) +
  geom_bar(stat = "identity", fill = "red", alpha = 0.5) +
  ggtitle(paste("Playmate of the Month: % of Non-US Models by Decade")) +
  labs(y = "% Playmates from outside US") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 15))

grid.raster(logo, width = 0.06, height = 0.08, x = 0.125, y = 0.96)

Ah, the 80s again. A.k.a the Middle Ages of the 20th century.

Play Over

Women get judged by their appearance constantly, by unrealistic standards. Playboy’s images are nothing compared to what current porn “has to offer”. I think we need to address this, and I just did, in my own way. I thought a lot about whether to censor the “Average Playmate” images and I decided they’re part of this story, as is. So be proud of your curves, ladies, if it were the 1950s you’d be on Playboy’s centerfold! And if you know of a website to fetch similar data regarding Playgirl’s male models - do tell. I’d love to see a graph of these men’s chest area covered with hair, through the years.


  1. Some months there was no Playboy issue, some months saw 2 or more playmates, etc.

  2. Or should I say erotic? pronographic?

  3. All are white, of course, Playboy isn’t very diversified.