• Moving Past Default Charts

    Posted to Tutorials  |  Tags: , ,

    For static data graphics my workflow typically involves R and Illustrator at varying degrees. I covered the process in Visualize This and provided an introduction on how to do the same with Inkscape, Illustrator's open source counterpart. However, you don't always have to use illustration software to produce more readable graphics.

    You can stay in R, tweak a few variables, and it might be all you need. If not, you can at least get closer to what you want, which makes for less post-editing. In this tutorial you learn what parameters to change to mimic a handful of popular chart styles.

    R is flexible, so you can draw whatever you want, but the point of this exercise is that a couple more lines of code can change your visuals quickly and easily.To make things interesting, I limited myself to base R graphics and did not start charts from scratch. The parameters had to be clearly specified in the documentation. No R packages allowed. No warnings allowed.


    If you haven't already, download R and install. Click on CRAN on the left of the R homepage, select a location near you, and download the installation that is meant for your computer. It's a relatively installation after that. You won't need any packages for this tutorial, but if you're keen on exploring, you can look at available packages via the Package Installer in R's main menu.

    I recommend you follow along with the downloaded code instead of typing in the snippets in this post. It's just less likely you get stuck on a typo mistake.Also download the code and data for this tutorial. Change the working directory in R via the main menu to wherever you save your files.

    Load data

    You will be charting life expectancy data. It's time series data from 1960 to 2009 for over 200 countries.

    # Load the data
    startYear <- 1960; endYear <- 2009
    life <- read.csv("data/life-expectancy-cleaned.csv", stringsAsFactors=FALSE)
    countryRegions <- read.csv("data/country-regions.csv", stringsAsFactors=FALSE)
    lifeComp <- na.omit(life)
    lifeReg <- merge(lifeComp, countryRegions, by.x="Country.Code", by.y="CountryCode")

    For the sake of simplicity, let's just take a subset of the data: the countries in East Asia and Pacific.

    # Subset East Asia and Pacific, for sake of simplicity
    eap <- subset(lifeReg, RegionName == "East Asia &amp; Pacific (all income levels)")
    minVal <- min(eap[,-c(1,2,53,54)])
    maxVal <- max(eap[,-c(1,2,53,54)])
    eapYears <- eap[,-c(1,2,53,54)]

    Helper function

    I wrote a small helper function to draw a line for each country. It takes the data, and you specify the colors and widths.

    # Helper function to draw a line for each country
    lifeLines <- function(series, col="black", hcol="black", lwd=1, hlwd=2, showPoints=FALSE) {
    	for (i in 1:length(series[,1])) {
    		lines(startYear:endYear, series[i,], col=col, lwd=lwd)
    	randomIndex <- sample(1:length(series[,1]), 1)
    	lines(startYear:endYear, series[randomIndex,], col=hcol, lwd=hlwd)
    	if (showPoints) {
    		points(startYear:endYear, series[randomIndex,], col=hcol, pch=4)


    Okay, time for some actual plotting. Start with R's plot() function to set axis limits, and then use the helper function lifeLines() to draw a line for each country in the data frame eapYears.

    # Default plot
    plot(0, 0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n")

    If you use R already, you should recognize the aesthetic of the chart below. All the lines are of the same width, the vertical axis labels are turned sideways, and a bounding box encapsulates the plotting region.

    Default R plot.01-Default plot with no options

    The plot() function has some arguments you can fill, such as axis limits, axis labels, and the main title. Fill those in, as shown below.

    # Deafult Plot Options
    plot(0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n", main="Life Expectancy in East Asia and Pacific", sub="Subtitle", xlab="Years", ylab="Age", asp=1/2)

    This gives you the same data, but shown in a slightly modified context.

    Still default but with a few more filled in values in the plot() function.02-Changed some options

    The sub argument allows you to specify a subtitle for the chart, but for some reason it's on the bottom. I'm not sure who thought of that bright idea, but it sort of makes the subtitle worthless. I never use it.

    Anyways, when you look at the two charts above, you think R. They look very R-ish, which I think is why so many people associate R with a certain type of chart. Let's try to change that perception right now.

    Work with parameters

    Some parameters that are not listed in the documentation can also be changed via par(), but let's use function strictly as intended.The par() function in R lets you change a lot of parameters for your current plotting device. It doesn't let you change everything, but there are a good number of options to play with. Some of the parameters you specify in par() you can also specify directly in plot(). My rule for this tutorial is that you can change stuff listed in the plot() and the par() documentation, but no switching or adding.

    I won't describe what very parameter does, so if you're curious about one, enter ?par in the R console to read a description.Start with las and bty, which change the orientation of axis labels and border type for the plotting region, respectively. Change the former to 1 so that labels are always horizontal and the latter to "n" to remove the border completely.

    # Simplified
    par(las=1, bty="n")
    plot(0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n", main="Life Expectancy in East Asia and Pacific", xlab="", ylab="Age", asp=1/2)
    lifeLines(eapYears, col="#cccccc")

    So there's three lines of code above. The first sets some parameters (las and bty), the second creates a plotting region, and the third uses our helper function lifeLines() to draw a light gray line for each country in the data.

    This gives you a plot of the same data as before, with a simplified look.

    Simplified plot with no outer border and tick labels turned around.03-Simplified

    What else can you change? Well, you can change font size, the margins (and outer margins) of a plot (or collection of plots), clipping region, the margin line for axes and their labels, and the end type of your lines (rounded or straight).

    With this in my mind, the code below makes a plot that looks newspaper-y. The axis label for age is smaller and bold, the tick labels are smaller, and the color of the highlighted line is a dark, neutral blue-green shade.

    # Newspaper
    par(mar=c(4, 4, 3, 1), oma=c(0,0,0,0), xpd=FALSE, xaxs="r", yaxs="i", mgp=c(2.1,.6,0), las=1, lend=1)
    plot(0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n", bty="n", las=1, cex.axis=0.8, cex.lab=0.8, main="Life Expectancy in East Asia and Pacific", xlab="", ylab=expression(bold("Age")), family="Helvetica", asp=1/2)
    grid(NA, NULL, col="black", lty="dotted", lwd=0.3)
    lifeLines(eapYears, col="dark grey", lwd=0.7, hlwd=3, hcol="#244A5D")

    In this snippet, grid() is called before lifeLines() to draw horizontal lines that match up with the y-axis. The lines are thin with a width of 0.3 and dotted.

    Kind of looks like a chart in a newspaper, right? I mean, most graphics in newspaper forgo the dark axis lines and just go with thin tick marks, but par() doesn't let you control that directly, so we won't do anything with that.

    A newspaper-ish plot with grid lines.04-Newspaperish

    You can also change background color and the font size and weight of your main title. So with that, and the parameters we know we can change from the snippet above, try a Feltron-style plot. Nicholas Felton, known for his annual personal reports, likes to use small fonts and contrasting background and foreground colors. Below uses the colors from his 2013 report.

    # Feltron
    par(bg="#36394A", mar=c(5, 4, 3, 2), oma=c(0,0,0,0), xpd=FALSE, xaxs="r", yaxs="i", mgp=c(2.8,0.3,0.5), col.lab="white", col.axis="white", col.main="white", font.main=1, cex.main=0.8, cex.axis=0.8, cex.lab=0.8, family="Helvetica", lend=1, tck=0)
    plot(0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n", bty="n", las=1, asp=1/2, main="LIFE EXPECTANCY IN EAST ASIA AND PACIFIC", xlab="", ylab="")
    lifeLines(eapYears, col="white", lwd=0.35, hcol="#E3DF0C", hlwd=3)

    Hey, this doesn't look like an R-ish chart.

    A Feltron-style plot with a dark background, thin lines, and smaller fonts.05-Feltron

    "But wait, where did the axis lines and ticks go? I thought you said par() doesn't let you mess with that stuff." Okay, you're right. I cheated and used axis() to put up the tick labels separately. The snippet below is what actually produced the chart above.

    # Axis change
    par(bg="#36394A", mar=c(5, 4, 3, 2), oma=c(0,0,0,0), xpd=FALSE, xaxs="r", yaxs="i", mgp=c(2.8,0.3,0.5), col.lab="white", col.axis="white", col.main="white", font.main=1, cex.main=0.8, cex.axis=0.8, cex.lab=0.8, family="Helvetica", lend=1, tck=0, las=1)
    plot(0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n", bty="n", las=1, asp=1/2, main="LIFE EXPECTANCY IN EAST ASIA AND PACIFIC", xlab="", ylab="", xaxt="n", yaxt="n")
    axis(1, tick=FALSE, col.axis="white")
    axis(2, tick=FALSE, col.axis="white")
    lifeLines(eapYears, col="white", lwd=0.35, hcol="#E3DF0C", hlwd=3)

    While you're in axis-drawing mode, how about a FiveThirtyEight-style chart? They typically use a light gray background with a grid that goes horizontal and vertical, and often forego any axis lines. The main title is bold, the axis labels are not, and the tick labels are dark gray, set at a medium font. They also like to use bold-ish but not super bright colors to highlight points, hence the bright blue life line.

    # FiveThirtyEight
    par(mar=c(3, 4, 3, 2), oma=c(0,0,0,0), bg="#F0F0F0", xpd=FALSE, xaxs="r", yaxs="i", mgp=c(2.1,.3,0), las=1, col.axis="#434343", col.main="#343434", tck=0, lend=1)
    plot(0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n", bty="n", las=1, main="Life Expectancy in East Asia and Pacific", xlab="", ylab="Age", family="Helvetica", cex.main=1.5, cex.axis=0.8, cex.lab=0.8, asp=1/2, xaxt="n", yaxt="n")
    grid(NULL, NULL, col="#DEDEDE", lty="solid", lwd=0.9)
    axis(1, tick=FALSE, cex.axis=0.9)
    axis(2, tick=FALSE, cex.axis=0.9)
    lifeLines(eapYears, col="dark grey", lwd=1, hlwd=3, hcol="#008ED4")

    Looks pretty FiveThirtyEight-ish to me.

    FiveThirtyEight-style plots with light gray background, thin grid lines, and no axis lines.FiveThirtyEight style

    One thing you haven't changed yet: the position of the axis labels. In a lot of publications, axis labels are left justified, but R center aligns them. There's a way to change that with par() in R (see adj), but it doesn't work very well. You can also change text position relatively easily if you start from scratch, but again, I want to limit that. I already went too far by using axis(). For shame.

    Back to the rules.

    Try on Economist-style for size. There is always the red rectangle in the top left corner, the light blue background, italicized axis labels, small tick labels, and ticks that point in towards the plot rather than out towards the labels, and white grid lines.

    Start with the red rectangle. Draw an empty plot with all margins set to zero, and then draw a rectangle with rect(). No border.

    # The Economist
    # Red corner rectangle
    par(xpd=NA, oma=c(0,0,0,0), mar=c(0,0,0,0), bg="#DCE6EC", xpd=FALSE, xaxs="i", yaxs="i", lend=1)
    plot(0, 0, type = "n", bty = "n", xaxt="n", yaxt="n", xlim=c(0,100), ylim=c(0,100))
    rect(0,100,2,94, col="red", border=NA)

    I have a feeling there's a better way to do this, as this feels kind of hack-ish, but it works and you get no warnings, so there.Then add another plot on top of that by setting new to TRUE in another call to par(), and then create another plot. Again, use grid() to draw the white horizontal lines across. The arguments cex.axis and cex.lab specify font size for axis labels and tick labels, respectively. By setting tck to 0.2, you create tick marks that point into the plotting region. A negative value makes them go outward.

    # Actual chart
    par(mar=c(4, 3, 3, 2), oma=c(0,0,0,0), xpd=FALSE, xaxs="r", yaxs="i", mgp=c(1.8,.2,0), cex.axis=0.7, cex.lab=0.7, col.lab="black", col.axis="black", col.main="black", tck=0.02, yaxp=c(minVal, maxVal, 2), new=TRUE)
    plot(0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n", bty="n", las=1, main="Life Expectancy in East Asia and Pacific", xlab=expression(italic("Years")), ylab=expression(italic("Age")), family="Helvetica", asp=1/2)
    grid(NA, NULL, col="white", lty="solid", lwd=1.5)
    lifeLines(eapYears, lwd=1.25, hlwd=2.5, col="#33A5A2", hcol="#244A5D")

    This gives you your Economist-style plot.

    Looks like the Economist, especially with the red rectangle in the top left corner.Economist style

    Getting the hang of it? We're plotting the data in the same way structurally, but changing the aesthetic with just one more line of code.

    Just for kicks, let's try a Tukey-like plot from his book Exploratory Data Analysis. At the time, people drew most of their charts by hand. Tukey used symbols, wrote small labels, and drew his tick marks inward.

    # Tukey
    par(las=1, tck=0.02, mgp=c(2.8,0.3,0.5), cex.lab=0.85, cex.axis=0.8, cex.main=0.9)
    plot(0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n", bty="n", main="Life Expectancy in East Asia and Pacific", xlab="", ylab="Age", asp=1/2)
    lifeLines(eapYears, col="#cccccc", hlwd=1.2, showPoints=TRUE)

    Looks similar to the simplified chart you made early in this tutorial.

    Trying to mimic Tukey with smaller labels, symbols, and inward-facing tick marks.08-Tukey

    Finally, just because we can, how about a dark background with neon bright lines. Looks kind of old school console.

    # Bright on Dark
    par(bg="black", las=1, tck=0, mgp=c(2.8,0.3,0), cex.lab=0.85, cex.axis=0.8, cex.main=0.9, col.axis="white", col.main="white", col.lab="white")
    plot(0, xlim=c(startYear, endYear), ylim=c(minVal, maxVal), type="n", main="Life Expectancy in East Asia and Pacific", xlab="Year", ylab="Age", asp=1/2)
    grid(NULL, NULL, lty="solid", col="white", lwd=0.5)
    lifeLines(eapYears, col="#f30baa", lwd=1.2, hcol="green", hlwd=3)

    Ooo, colors.

    09-Neon something or other

    Wrapping up

    Here's what we learned:

    1. Sticking to default settings on our charts is easy, but so is customizing them.
    2. The par() function in R is your friend. Unless you use it a lot you probably won't remember all the parameter names (I still don't), but you can always consult the documentation with ?par.
    3. R charts don't have to look like "R charts."

    Some people even paint in Excel.Customization doesn't just apply to R. Maybe you use Excel or some other tool that has a reputation for ugly. More often than not, it's not that hard to change the look and readability. So you're not stuck with default.

    However, remember that this is just a start. Because R lets you draw lines, shapes, and text how you want, you can customize a lot more. The point isn't that you can mimic other styles. It's that there's enough flexibility to create your own.

    Personally, I stick with my R and Illustrator workflow, but the closer I can get to a finished graphic on the first go, the less time I have to spend hand-editing.

  • F1 racing winners and age

    Posted to Infographics  |  Tags: , ,

    So here's a sport I don't see or hear much about. F1 racing, which requires a different sort of strength and agility than say football or basketball, has a wide range of ages. Drivers can be in their teens. Some are in their late 40s (and successful). Peter Cook visualized the ages and races of drives through F1 racing history, since 1950.

    Each row represents a driver's career, and each color-coded dash in a row represents a race. Colors indicate wins, a trip to the podium, and a top 10 finish.

    My favorite part is the tour on initial load. The interactive points out highlights in the data, such as the youngest, oldest, and drivers of interest.

  • Cynthia Brewer profile

    Posted to Mapping  |  Tags: , ,

    Wired wrote a short profile for Cynthia Brewer, best known for Color Brewer, a tool that provides visually apt color schemes for maps (and charts).

    Brewer has been thinking about these issues since her graduate days at Michigan State. But the idea for Color Brewer grew out of a sabbatical she did with the U.S. Census Bureau, overseeing the atlas that accompanied the 2000 Census. "We were trying to be really systematic with color throughout the atlas," she said. Other mapmakers liked the color sets they developed and began asking for them, and Brewer set up Color Brewer to make them more readily available.

    If you've looked at thematic maps at all, you've likely come across a color scheme from Color Brewer. I wouldn't say it's ubiquitous quite yet, but it's close. I just like how something so widespread came from a couple of people in a room who wanted to streamline the process of putting together the decennial atlas.

  • Your life on Earth

    Posted to Infographics  |  Tags: , ,

    The BBC has a fun piece that shows changes over your lifetime. Enter your date of birth, gender, and height, and you get personalized data nuggets, categorized by how you changed, how the world changed, and how people changed the world during your years on this planet.

    For me: 161 major volcano eruptions, 72 solar eclipses, and a 2.7 billion increase in global population.

    Naturally, as with most global numbers, these are based on estimates from a wide range of sources, so keep that in the back of your mind as you scroll.

  • A healthy versus unhealthy office environment

    Posted to Infographics  |  Tags: , ,

    In an interesting use of the before-and-after slider, this Washington Post graphic by Bonnie Berkowitz and Laura Stanton contrasts an unhealthy office environment against a healthy one.

    As a whole, the graphic represents a full office, and the section is broken into categories for an unhealthy environment on the left and a healthy one on the right. For each section, slide all the way to the left or right to see a fuller picture of the respective habit, covering topics such as ergonomics, hygiene, and air quality.

    FYI: Rats and dead plants send the wrong message to your employees.

  • Data Fluency, Coming Soon

    Posted to Data Fluency

    Data FluencyThere's a new addition to the FlowingData book series on the way. It's called Data Fluency: Empowering Your Organization With Effective Data Communication. It's by the founders of Juice Analytics Zach and Chris Gemignani and is available for pre-order at the major online booksellers. Copies are also making their way to the brick-and-mortars.


    As I assumed the technical editor role for the first time, I'll talk more about the book soon, but Zach and Chris probably sum it up best:

    Our hope is that this book starts a new kind of conversation in the analytics field — one that incorporates the people side as much as the tools, techniques, and technologies. We hope it spurs individuals and organizations to start on a journey toward making data a more useful tool for sharing ideas.

    Pre-order it on Amazon.

  • Map of book subjects on Internet Archive

    The Internet Archive makes millions of digitized books available in the form of scanned pages, and these books are categorized into thousands of subjects. Focusing on book images, Mario Klingemann mapped subjects, based on tag similarity. Browse and discover new reading material.

    This map offers an alternative way to browse the 2,619,833 images contained in the Internet Archive's book collection. It shows 5500 different subjects which have been algorithmically arranged by their thematic relationships. The size of each link resembles the amount of images that are available for that topic. Clicking on a link will open the flickr page containing all the pictures for that subject. Rolling over a link will highlight all the topics that have a direct link with the subject.

    I recommend browsing towards the middle in the medical cluster for some weird, old-school healing techniques.

  • How basketball rebounds work

    Kirk Goldsberry, with help from Andy Woodruff, looked at how rebounds work in the NBA from a statistical perspective.

    When a player shoots the ball and misses, there's a tendency for the ball to go in certain directions and distances. Long shots for example often mean long rebounds away from the basket. After years of experience, players gain an intuition for these sort of bouncebacks and can try to position themselves for a rebound. These days more detailed data (via camera technology) is available, which is what these court maps show.

    The interactive version in the middle of the article is especially interesting. Mouse over the court, and you can see where players typically rebound after a missed shot from the selected spot.

  • Equal population mapper

    Posted to Mapping  |  Tags: , ,

    We know that there are more people per square mile in some places than others, but it can be a challenge to understand the magnitude of the differences. The same goes for the other way around. So Ben Blatt for Slate made the Equal Population Mapper, which lets you select an area of interest such as Los Angeles county or the state of Wyoming and see how many counties it takes to equal the population of said area.

    For example, the above shows coastal counties as the point of reference, and you see the counties it takes to equal the coastal population in red. That's a big section in the middle.

    Might remind you of the Per Square Mile project from a while back which used cities around the world as point of reference and US states as the mode of comparison.

  • Road grid orientation in major cities

    Posted to Mapping  |  Tags: , ,

    This is what you get when you group streets by their geographic orientation and color them accordingly with a neon paintbrush. From the ever curious Stephen Von Worley:

    That's every public street, colored by the predominant orientation of itself and its neighbors, thickened where the layout is most "grid-like" — to use an old-school woodworking metaphor, it's as if we brushed some digital lacquer over the raw geographic transportation network data to make the grain pop.

    Above is the map for Los Angeles. You see a lot of north-south grids in the red-orange color, but head towards the center of the map in the downtown area, and you get pockets of misdirection. In cities like Tokyo and Paris it looks like there's no order at all to the roads, whereas Chicago's road network looks like one big grid.

    Lots to ponder, especially if you live in the cities.

    See also the level of gridded-ness by Seth Kadish.

  • Linked Small Multiples

    Small multiples should be a familiar visualization technique for most FlowingData readers. The key idea is to slice up your data and use a separate plot to visualize each slice. The end result is a grid of charts that all follow the same visual format, but show different pieces of the data.

    Essentially, a chorus of little stories to help tell a bigger one.
     Continue Reading 

  • Geographic smell maps

    Posted to Data Art  |  Tags: ,

    Kate McLean, a PhD candidate in Information Experience Design at the Royal College of Art, is interested in the senses. More specifically, the non-visual ones. Mainly our sense of smell. As she tags herself as an olfactory experience designer, McLean goes on smellwalks, documents aromas, and then maps the "smellscapes."

    The map above is for Amsterdam, which you expect to smell like pot all day everyday and everywhere. But it didn't.

    Instead spring 2013 in Amsterdam revealed an abundance of the warm, sugary, powdery sweetness of waffles. Oriental spices emanated from Asian and Surinamese restaurants and supermarkets, pickled herring from the herring stands and markets — a link to one of the city’s key historical industries. Old books were detected in basement doorways and laundry aromas drifted up into the streets from Amsterdam's many house hotels.

    More smell maps: New York, Rhode Island, Paris, and Milan.

  • 10,000 League of Legends matches, all at once

    League of Legends is an online, free-to-play game that pits two teams of five against each other. The goal is to destroy the other team's structures. The New York Times mapped 10,000 matches, played by 100,000 players, showing player movements over a quick thirty seconds.

    As you'd expect, you see a lot of battles in the middle of the field and if you play the game, you're likely to recognize the paths that people usually take. The best part is the character breakouts that show how certain "champions" move about.

    Reminds me of the point cloud that shows over 11 million deaths in Just Cause 2.

  • Fallacy of point-and-click analysis

    Posted to Statistics  |  Tags: ,

    Jeff Leek touches on concerns about point-and-click software to find the insights in your data, magically and with little to no effort.

    I understand the sentiment, there is a bunch of data just laying there and there aren't enough people to analyze it expertly. But you wouldn't want me to operate on you using point and click surgery software. You'd want a surgeon who has practiced on real people and knows what to do when she has an artery in her hand. In the same way, I think point and click software allows untrained people to do awful things to big data.

     Continue Reading 

  • Ebola spreading, a simulation

    Posted to Infographics  |  Tags: ,

    As a way to understand the deadliness and spread of Ebola, the Washington Post runs a simplified simulation of how long it's likely to take for the virus to infect 100 unvaccinated people. The simulation runs alongside several other diseases for comparison, which provides the main takeaway: Ebola is much more deadly than the other listed diseases, but it spreads much slower.

  • Skateboard physics

    Posted to Infographics  |  Tags: ,

    Aatish Bhatia, a recent physics PhD, describes the forces involved to do a skateboard Ollie. It's all about managing your center of gravity and applying variable amounts of torque to steer the board in the air. Yeah. It probably won't help you skate any better, but it'll help you appreciate the tricks a little more. [via kottke]

  • Interracial and same-sex marriage parallels

    Posted to Infographics  |  Tags: ,

    xkcd doing what xkcd does. Randall Munroe charts a brief timeline of interracial and same-sex marriage, through the lens of popular approval and population.

  • Tracking online ads

    We browse online, we see ads, and we buy stuff. The better-targeted the ads are, the more likely that we buy stuff. So of course advertisers continue on ways to guess who you are and what you might want to increase the chances that you click and spend. Floodwatch, a Chrome extension by the Office for Creative Research and Ashkhan Soltani, lets you turn it around ever so slightly so that you can track what the advertisers serve you.
     Continue Reading 

  • Why pursue a PhD

    Posted to Miscellaneous  |  Tags:

    Philip Guo provides three practical reasons on why it's worth pursuing a PhD.

    Worth considering if you're hemming and hawing about graduate school. Then again, it's just as easy to come up with three practical reasons on why it's not. Let's not get into that though. Yeah, good luck with that.

    Already on you way to a PhD? See also a survival guide to finishing.

  • Deviations from the mean

    As a way to bring context to the rarity of the 18-inning baseball game between the Washington Nationals and the San Francisco Giants this past weekend, Ross Benes compared other things that are 9.1 standard deviations from the mean.

    An NBA team losing by 83 points. A 13.4-inch penis.

    I'm not so sure how comparable those distributions are (as in deviations from the mean doesn't always mean the same thing), but it's an interesting exercise. At the very least, it's a new tumblr in the making.