Before our guest lecturer, I took a sneak peek at the csv file we would be using for data viz practice. Admittedly, I was a little disappointed to find out that it was a small sampling of popular names. Surely, not many interesting things could come out of that! But as Lin said, some of the more interesting discoveries come from exploring and messing around with weird data in weird ways. While listening, I passively went through some combinations of columns that could possibly tell an interesting story, as well as mutations to the data (e.g., just the first letter of the name, the parity of the year…)
At some point I came to the combination of “Name vs. Year”, and then eventually “Length of Name vs. Year”. “Haha“, I thought “I sure do know a lot of people named Ben (and other short names), I wonder if names have gotten shorter over time“
I really didn’t expect anything out of it. However!
Below is the graph:
This was generated with a programming library called Plotly.NET, using a niche programming language that I found over the pandemic called F#. It’s similar to C# but uses more “functional” features like currying. I wanted to shake off some rust with the language, because it’s been a while since I’ve used it. In addition, there is a very liberating sense of being able to explicitly state how one wants to present their data. With a premade tool, common graphs are easy and much quicker to generate. However, it is hard to customize your graph beyond the basics. A good example is when I wanted to change the text that displayed when you hover over a circle (try it!). The default option only displays the x axis value and the y axis value. I also wanted it to display the top three names. The task was quite easy using a programming environment (though admittedly not entirely trivial, because documentation was annoying to sift through here. If at any point I disliked a feature, I could navigate to the exact line that was causing trouble.
As for the graph itself, the goal of this assignment was to tell a story. A story in this case is a downward trend, that is, we want to show clearly that the average length of names has gone down. A scatter plot seemed best here, along with a line to show continuity through time (though in the code I found it easier to just make a line chart and add markers.) While the data definitely had a moving downward trend, I didn’t want the two upward spikes to interfere with the narrative. Whereas it would have been more professional to draw some sort of line of best fit, or perhaps reevaluate the data as a whole, I opted to just hide the noise. As you see, any dot that isn’t going down has an opacity of 10%.
When I first presented a draft of the graph, I was told that it looked fine, but it could stand to be even simpler than it was. Reduction of noise was a big topic in Lin’s lecture, Among many other things I changed from the default options, I took away the background shading, removed any gridlines, and opted to have the tick mark labels further apart.
Here is the code, for those curious:
open System.Drawing
open System.IO
open Plotly.NET
open Plotly.NET.LayoutObjects
open Plotly.NET.StyleParam
open Plotly.NET.TraceObjects
type PopularName =
{
Rank: int
Year: int
Name: string
Gender: string
Count: int
}
let parseLine (line: string) =
let fields = line.Split ','
{
Rank = int fields[0]
Year = int fields[1]
Name = fields[2]
Gender = fields[3]
Count = int fields[4]
}
let results =
File.ReadAllLines(
@"C:\Users\mason\RiderProjects\GraphingDataProject\GraphingDataProject\10MostPopularBabyNamesUSA_2001-2010(Sheet1).csv"
)
|> Array.skip 1
|> Array.map parseLine
let data =
results
|> Array.groupBy _.Year
|> Array.map (fun (year, names) ->
let averageLength =
Array.averageBy (fun n -> float n.Name.Length) names
let topThree =
names
|> Array.sortBy _.Rank
|> Array.truncate 3
|> Array.map _.Name
year, averageLength, topThree
) |> Array.sortBy (fun (year, _, _) -> year)
let yaxis =
LinearAxis.init (
Title = Title.init("Average Name Length", Font.init FontFamily.Open_Sans),
ShowLine = true,
ShowGrid = false,
Ticks = TickOptions.Inside,
DTick = 0.5,
Minor = Minor.init(
Ticks = TickOptions.Inside,
DTick = 0.1,
ShowGrid = false
)
)
let xaxis =
LinearAxis.init (
Title = Title.init("Year", Font.init FontFamily.Open_Sans),
ShowLine = true,
ShowGrid = false,
Ticks = TickOptions.Inside,
AxisType = AxisType.Linear,
DTick = 2,
Minor = Minor.init(
Ticks = TickOptions.Inside,
DTick = 1
)
)
let xy = data |> Array.map (fun (year, avg, _) -> year, avg)
let labels =
data |> Array.map (fun (year, average, names) ->
$"""Year: %A{year}<br>Average Length: %A{average}<br>Top Names: %s{String.concat ", " names}""")
let title = Title.init("Average Length of Most Popular Baby Names Over Time", Font.init FontFamily.Open_Sans, XRef = "paper")
let chart = Chart.Line(xy = xy,
ShowMarkers = true,
MarkerSymbol = MarkerSymbol.Circle,
MultiText = labels)
|> Chart.withLineStyle(
Dash = DrawingStyle.Dot,
Color = Color.fromKeyword LightBlue)
|> Chart.withMarkerStyle(
Color = Color.fromKeyword DarkBlue,
MultiOpacity = seq { 1; 1; 0.1; 0.1; 1; 0.1; 0.1; 0.1; 1; 1 })
|> Chart.withTitle title
|> Chart.withXAxis xaxis
|> Chart.withYAxis yaxis
|> Chart.withLayoutStyle(
PlotBGColor = Color.fromKeyword White,
PaperBGColor = Color.fromKeyword White
)
chart |> GenericChart.toEmbeddedHTML |> printf "%A"
1 thought on “Haha Surely this Won’t Yield Any Significant! Wait, what?”