Brief Update

Sorry followers!

With moving, traveling, dealing with a wrecked car, and finishing my dissertation, I’ve fallen behind on blogging. I miss it and I will start again soon! In the meantime, instead of sharing my usual impersonal blog posts where I share a tutorial or give tips on teaching or policy communication, I will share some photos from my trip. Hope you enjoy!

Glacier National Park
Sunrise at Glacier National Park


peter lougheed provincial park
From Peter Lougheed Provincial Park in Canada
lake louise
Lake Louise, Banff National Park
Morraine Lake
Moraine Lake, Banff National Park
Interesting halo effect of me taking a picture of the ice fields in Jasper National Park


Unplanned stop in Jasper
Near our unplanned campsite in Jasper–the road was closed because of a large car accident. Sixteen people lost their lives in Jasper that weekend…
Mochi enjoying the serene lake in Jasper National Park
Foggy day on the coast of Washington
Encounter with a banana slug
My closest encounter with a chipmunk at Crater Lake
Where the car broke down–i.e., middle of nowhere Nevada
The salt flats in Utah. The last picture before returning to Colorado.

Fact-checking Vancouver’s Swamp Drainers

Home: Free Sociology!

[co-authored with Jens von Bergmann and cross-posted with MountainMath]

Swampy facts: the dark, broken, and ugly side of housing talk in Vancouver.

Down south of the border, a politician who shall remain nameless campaigned on “draining the swamp” of Washington D.C., trafficked in countless conspiracies, and lied his way into office. His lies painted a picture of a United States turned dark, corrupt and menacing. He promised to fix it, Making American Great Again, mostly by shutting down globalization and kicking out the immigrants.

In Canada, we like to think we’re immune to this kind of rhetoric. But a strain has made its way into discussions concerning Vancouver, where the intersection of real estate, politics, and globalization are increasingly portrayed as a swamp in need of draining. We don’t believe most of those portraying Vancouver as swamp-like are intentionally lying (and in real life they surely favour the preservation…

View original post 1,995 more words

Article & Media Roundup 715/18-7/22/18

Article & Media Roundup 715/18-7/22/18

^image: Since 1996, more than 1 million U.S. babies have been born as a result of assisted reproductive technology (ART). See link from the PEW below


According to Weldon Cooper Center for Public Service of the University of Virginia, In about 20 years, half the population will live in eight states

15min video explaining cousins–also see CPG Grey’s 4min video on family trees

Although the average household size (i.e., the number of people living in a house) has decreased from 3.33 in 1960 to 2.54 in 2017, the average house size has increased by 18.5 square ft. since the 1920s

On average, 33% of American adults report that they or someone they know has used some type of fertility treatment in order to try to have a baby, according to a new Pew Research Center survey. The experience is more common with higher levels of education.

First marriage rates slightly declined in 2016

Explaining the Gap between Fertility Ideals and Intentions in Four Postindustrial Societies

From 2009 to 2016 there was a 10.5 percent annual increase on average in cirrhosis-related mortality among people ages 25 to 34.


Economics of Uber (9min video)

Corporate debt has surged, and it’s a global problem

More and more students are hitting the cap on student loans, and more parents are borrowing to fill the gap as a result


New Census Bureau research using both Census and IRS data shows that when wives earn more than their husbands do, husbands say they earn more than they actually are while wives under report their income.–See also the Upshot

Article & Media Roundup 7/8/18-7/15/18

Article & Media Roundup 7/8/18-7/15/18

^image: changing patterns in interracial/interethnic marriage by the U.S. Census Bureau. See link below.


Areas at highest risk of flooding in the U.S.

Research linking air pollution to diabetes


The extinction of the middle child

Free eBook! — Visualizing Mortality Dynamics in the Lexis Diagram

A recent study on the water crisis in Flint, Michigan, showed that fertility rates dropped by 12% and fetal deaths rose by 58% after lead contamination spiked in the city’s drinking water.

U.S. Urban Rural Divide in Marriage

“As our nation becomes more racially and ethnically diverse, so are married couples.”

A peek into Japanese dating apps

Interactive tool that shows how much you make depending on where you live

8% gap in home ownership between Millennials and Gen X, which is unlikely to closeStudent debt is part of the issue

Visual breakdown of US gayborhoods

New CDC report on US Fertility

New York cemeteries are running out of space, and the cost of burials are rising as a result

The number of families with small children who rent now outnumbers the number of families with small children who own their homes

Tech, Science, & Privacy

Consumer behaviors can tell researchers a lot about a person

The hyper-integration of Chinese businesses, tech, and government, and what it means for privacy


Teachers rated as more attractive on tend to be rated higher on other metrics like quality, clarity and helpfulness.

Race & Inequality

Negative spillover effects for the mental health of Black Americans after police shootings of unarmed Black victims

2018 World Population Day!

2018 World Population Day!

Happy World Population Day!

In case you’re unfamiliar with World Population Day, it started in 1989 by the Governing Council of the United Nations Development Programme. July 11th was chosen because in 1987, it marked the approximate date in which the world’s population reached 5 billion people. The purpose of World Population Day is to draw attention to issues related to the global population, including the implications of population growth on the environment, economic development, gender equality, education, poverty, and human rights. The latter issue is the theme celebrated this year. Specifically, family planning as a human right, as this year marks the 50th anniversary of the 1968 International Conference on Human Rights, where family planning was for the first time globally affirmed to be a human right.

This year, the world population is estimated to be around 7,632,819,325 people. If you want to see estimates of the global population in real time, you can visit the Worldometers website, which will also show other interesting estimates of population-related statistics, such as healthcare expenditures, energy consumption, and water use. If you’re interested in where they get their data and their methods, you can visit their FAQ section.

World Population #Rstats Edition

In celebration of World Population Day, I thought I would share an R program that pulls data from the Worldometers site:


and creates a world map that highlights the top 10 countries with the largest total populations:

The top 10 countries with the largest total populations is highlighted in dark green.

R code below:

#Load libraries
#Retrieve data:
html.global_pop <- read_html("")

#Create dataframe
df.global_pop_RAW <- html.global_pop %>%
  html_nodes("table") %>%
  extract2(1) %>%

#Check data

#Check for unnecessary spaces in values

#Check if country names match those in the map package
as.factor(df.global_pop_RAW$`Country (or dependency)`) %>% levels()

#Renaming countries to match how they are named in the package
df.global_pop_RAW$`Country (or dependency)` <- recode(df.global_pop_RAW$`Country (or dependency)`
                                   ,'U.S.' = 'USA'
                                   ,'U.K.' = 'UK')

#Convert population to numeric--you have to remove the "," before converting 
df.global_pop_RAW$`Population (2018)`<-as.numeric(as.vector(unlist(gsub(",", "",df.global_pop_RAW$`Population (2018)` ))))
sapply(df.global_pop_RAW,class) #Check that it worked

#Generate a world map
world_map<- map_data('world')

#Join map data with our data
map.world_joined <- left_join(world_map, df.global_pop_RAW, 
                              by = c('region' = 'Country (or dependency)'))

#Take only top 10 countries
df.global_pop10 <- df.global_pop_RAW %>%

#Printing to check

#Change data to numeric
df.global_pop10$`Population (2018)`<-as.numeric(as.vector(unlist(gsub(",", "",df.global_pop10$`Population (2018)` ))))

#Check if worked correctly

#Join map data to our data
map.world_joined2 <- left_join(world_map, df.global_pop10, 
                              by = c('region' = 'Country (or dependency)'))

#Create Flag to indicate that it will be colored in for the map
map.world_joined2 <- map.world_joined2 %>%
  mutate(tofill2 = ifelse(`#`), F, T))

#Now generate the map
ggplot() +
  geom_polygon(data = map.world_joined2, 
               aes(x = long, y = lat, group = group, fill = tofill2)) +
  scale_fill_manual(values = c("lightcyan2","darkturquoise")) +
  labs(title =  'Top 10 Countries with Largest populations (2018)'
       ,caption = "source:") +
  theme_minimal() +
  theme(text = element_text(family = "Gill Sans")
        ,plot.title = element_text(size = 16)
        ,plot.caption = element_text(size = 5)
        ,axis.text = element_blank()
        ,axis.title = element_blank()
        ,axis.ticks = element_blank()
        ,legend.position = "none"

Alternatively, you could include all the countries and use a gradient to indicate population size. However, China and India’s population is so large relative to other countries that it becomes difficult to see any real comparison.

#Generate map data (again)
world_map<- map_data('world')

#re-join with data
map.world_joined <- left_join(world_map, df.global_pop_RAW, 
                              by = c('region' = 'Country (or dependency)'))

#flag to fill ALL countries that match with the map package
map.world_joined <- map.world_joined %>%
  mutate(tofill = ifelse(`#`), F, T))

#Check that it worked correctly

#Then generate new map
ggplot(data = map.world_joined, aes(x = long, y = lat, group = group), color="white", size=.001) +
  geom_polygon(aes(x = long, y = lat, group = group, fill = `Population (2018)`)) +
  scale_fill_viridis(option = 'magma') +
  labs(title =  'Top 10 Countries with Largest populations'
       ,caption = "source:") +
  theme_minimal() +
  theme(text = element_text(family = "Gill Sans")
        ,plot.title = element_text(size = 18)
        ,plot.caption = element_text(size = 5)
        ,axis.text = element_blank()
        ,axis.title = element_blank()
        ,axis.ticks = element_blank()

Which should produce this map:
You can see that the other countries that made the top 10 list are not black, which reflects the smallest population sizes, but this map really just highlights how large China and India’s population are relative to the other countries.

More population data and viz

If you want to know more about the global population and how it has changed over time, here are some great resources:

Our World in Data— see also their estimates for future population growth

8 min PBS video

Hans Rosling Tedx video (10 min)

20 min Hans Rosling video –this uses the gapminder data I often code with in Python and in R

Kurzgsagt animated video (6.5 min)

If you’re interested in theories and analytical concepts of demography, here are some links to free online class material:

Johns Hopkins Demographic Methods –or here

Johns Hopkins Principles of Population Change



Around the Web 7/1/18-7/8/18

Around the Web 7/1/18-7/8/18

^image: Regional water use from Reddit’s Data Is Beautiful


A visual explanation of the Census

Unmarried women over 55 is one of the largest, and fastest-growing, demographics of home buyers

Economic barriers are among the top reasons for postponing motherhood or having fewer babies

Resources & Environment

Informative 9 min. video on Plastic Pollution

We are running out of sand! –7.5min video

Global climate change may accelerate gentrification.

As Americans Age, Their Support for Environmentalism Declines

Science, Privacy, & Tech

The rise of surveillance capitalism

Silicon Valley’s Exclusive Salary Database

Technology and language

A project to encourage researchers to state that they’ve lost confidence in their previous study

Health & Well-being

Research indicates that expanding access to Medicare has overall been beneficial

Empirical research on the effects of family separation on children’s well-being

Diabetes linked to air pollution


“There are now more women in law school than ever before, but men still lead the pack when it comes to private practice, making up about two-thirds of attorneys in this sector of the legal profession with gender-discrimination suits being filed by women at breakneck speeds.”


For the first time in the 18 years that Gallup asked the question, a majority of Americans did not say they were “extremely proud” to be American.

“America is a nation of immigrants, and its economy is propelled and activated by its openness to immigration and the new ideas and entrepreneurial energy that immigrants provide.”

Data Science

Python v. (and) R for Data Science


Publishing Opportunities for Demographers

Applied Demography News Letter

Population Research and Policy Review is now accepting research briefs

Plotly 3.0.0 in Jupyter Notebook

Plotly 3.0.0 in Jupyter Notebook 3.0.0 was recently released, and I finally got a chance to tinker with it! This is exciting because this release includes features that are specifically designed for Jupyter Notebooks. Namely, JavaScript is directly embedded in the figure that you can now access directly through your notebook. Exciting!

If you haven’t installed plotly or need to upgrade, open your Anaconda command prompt (as Administrator) and follow these directions. After you install plotly, launch Jupyter Notebook (by typing “Jupyter Notebook” into your Anaconda command prompt or by opening Jupyter Notebook using your computer menu). Next, enter your plotly username and api key in your notebook. You can sign up for plotly here. Directions for generating an api key here.

#first import plotly and provide username and api key
import plotly'UserName', api_key='XXXXX')

Now load the following:

import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import numpy as np
import pandas as pd

init_notebook_mode(connected=True) #tells the notebook to load figures in offline mode

Plotly should now work within your notebook.

Here’s an example of a 2D plot:

        {'x': x, 'y': y, 'type': 'histogram2dcontour'}

newplotExample of a 2D plot with markers:

x = np.random.randn(2000)
y = np.random.randn(2000)
iplot([go.Histogram2dContour(x=x, y=y, contours=dict(coloring='heatmap')),
       go.Scatter(x=x, y=y, mode='markers', marker=dict(color='white', size=3, opacity=0.3))], show_link=False)

newplot(1)Example of a 3D plot:

s = np.linspace(0, 2 * np.pi, 240)
t = np.linspace(0, np.pi, 240)
tGrid, sGrid = np.meshgrid(s, t)

r = 2 + np.sin(7 * sGrid + 5 * tGrid)  # r = 2 + sin(7s+5t)
x = r * np.cos(sGrid) * np.sin(tGrid)  # x = r*cos(s)*sin(t)
y = r * np.sin(sGrid) * np.sin(tGrid)  # y = r*sin(s)*sin(t)
z = r * np.cos(tGrid)                  # z = r*cos(t)

surface = go.Surface(x=x, y=y, z=z)
data = [surface]

layout = go.Layout(
    title='Parametric Plot',
            gridcolor='rgb(255, 255, 255)',
            zerolinecolor='rgb(255, 255, 255)',
            backgroundcolor='rgb(230, 230,230)'
            gridcolor='rgb(255, 255, 255)',
            zerolinecolor='rgb(255, 255, 255)',
            backgroundcolor='rgb(230, 230,230)'
            gridcolor='rgb(255, 255, 255)',
            zerolinecolor='rgb(255, 255, 255)',
            backgroundcolor='rgb(230, 230,230)'

fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='jupyter-parametric_plot')
Interact with it here

Lastly, an animated plot:

from plotly.offline import init_notebook_mode, iplot
from IPython.display import display, HTML


url = ''
dataset = pd.read_csv(url)

years = ['1952', '1962', '1967', '1972', '1977', '1982', '1987', '1992', '1997', '2002', '2007']

# make list of continents
continents = []
for continent in dataset['continent']:
    if continent not in continents:
# make figure
figure = {
    'data': [],
    'layout': {},
    'frames': []

# fill in most of layout
figure['layout']['xaxis'] = {'range': [30, 85], 'title': 'Life Expectancy'}
figure['layout']['yaxis'] = {'title': 'GDP per Capita', 'type': 'log'}
figure['layout']['hovermode'] = 'closest'
figure['layout']['sliders'] = {
    'args': [
        'transition', {
            'duration': 400,
            'easing': 'cubic-in-out'
    'initialValue': '1952',
    'plotlycommand': 'animate',
    'values': years,
    'visible': True
figure['layout']['updatemenus'] = [
        'buttons': [
                'args': [None, {'frame': {'duration': 500, 'redraw': False},
                         'fromcurrent': True, 'transition': {'duration': 300, 'easing': 'quadratic-in-out'}}],
                'label': 'Play',
                'method': 'animate'
                'args': [[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate',
                'transition': {'duration': 0}}],
                'label': 'Pause',
                'method': 'animate'
        'direction': 'left',
        'pad': {'r': 10, 't': 87},
        'showactive': False,
        'type': 'buttons',
        'x': 0.1,
        'xanchor': 'right',
        'y': 0,
        'yanchor': 'top'
#custom colors
custom_colors = {
    'Asia': 'rgb(171, 99, 250)',
    'Europe': 'rgb(230, 99, 250)',
    'Africa': 'rgb(99, 110, 250)',
    'Americas': 'rgb(25, 211, 243)',
    'Oceania': 'rgb(50, 170, 255)'
sliders_dict = {
    'active': 0,
    'yanchor': 'top',
    'xanchor': 'left',
    'currentvalue': {
        'font': {'size': 20},
        'prefix': 'Year:',
        'visible': True,
        'xanchor': 'right'
    'transition': {'duration': 300, 'easing': 'cubic-in-out'},
    'pad': {'b': 10, 't': 50},
    'len': 0.9,
    'x': 0.1,
    'y': 0,
    'steps': []

# make data
year = 1952
for continent in continents:
    dataset_by_year = dataset[dataset['year'] == year]
    dataset_by_year_and_cont = dataset_by_year[dataset_by_year['continent'] == continent]

    data_dict = {
        'x': list(dataset_by_year_and_cont['lifeExp']),
        'y': list(dataset_by_year_and_cont['gdpPercap']),
        'mode': 'markers',
        'text': list(dataset_by_year_and_cont['country']),
        'marker': {
            'sizemode': 'area',
            'sizeref': 200000,
            'size': list(dataset_by_year_and_cont['pop'])
        'name': continent
# make frames
for year in years:
    frame = {'data': [], 'name': str(year)}
    for continent in continents:
        dataset_by_year = dataset[dataset['year'] == int(year)]
        dataset_by_year_and_cont = dataset_by_year[dataset_by_year['continent'] == continent]

        data_dict = {
            'x': list(dataset_by_year_and_cont['lifeExp']),
            'y': list(dataset_by_year_and_cont['gdpPercap']),
            'mode': 'markers',
            'text': list(dataset_by_year_and_cont['country']),
            'marker': {
                'sizemode': 'area',
                'sizeref': 200000,
                'size': list(dataset_by_year_and_cont['pop'])
            'name': continent

    slider_step = {'args': [
        {'frame': {'duration': 300, 'redraw': False},
         'mode': 'immediate',
       'transition': {'duration': 300}}
     'label': year,
     'method': 'animate'}

figure['layout']['sliders'] = [sliders_dict]

Interact with it here

Neat, right?!


Overall, everything ran smoothly except the last plot. I actually initially tried to make this one:

From: (scroll to the bottom)

but I kept getting an error:


Update: Jon commented and pointed out that I was using an older version of plotly (3.0.0rc10) instead of 3.0.0rc11. You can check which version you have by typing the following:

import plotly

After I updated plotly, I successfully made the last graph!

Interact with it here

Special thanks to Jon! I sincerely appreciate your help!