Wednesday, January 1, 2014

Top Albums of 2013

Top Albums of 2013

Background

Spotify is pretty amazing - not the free version (I think I still prefer Pandora radio for that) - it has to be the paid version to really get the full effect. It has figuratively opened my mind to music that I never before would have considered (and some I will continue to deride). Although I still tend to stay within the confines of classic rock mixed with more modern indie and alternative rock, I have certainly explored and expanded more this past year than before. The biggest undertaking I accomplished was listening to each of the 500 albums listed in the Rolling Stone's 500 Greatest Albums of All Time (the May 2012 updated list, many, but not all are available on Spotify). Although I don't have an exact count, I have listened to well over 600 albums this year. When I think about it, I don't know how many albums I listened to before this year, but it couldn't have been a ton more than that.

I decided to rank my favorite albums of 2013, and when I say rank, I mean it has to involve some form of measurement. I find it very difficult to make "top-x lists," and am often very critical of such lists. One thing that drives me crazy is when radio stations have marathons over some holiday weekend of the "top 100 songs of all time, as voted by you, the listener!" When it is actually "We let you, the listener, go to our website and pick 5 songs from our catalog (I'm not sure who actually does this, but it couldn't possibly be representative of the actual listening audience, or am I wrong?), which is limited to 'classic' rock of the 60s, 70s, and maybe 80s." You then end up with weird things like Boz Scaggs' "Lido Shuffle" being ranked higher than Fleetwood Mac's "Go Your Own Way." 

While I can't promise that I won't have infuriating choices, I can at least be upfront about the rules I am playing by. Rules which are: I am limiting my list to the top albums of 2013 that I personally have listened to at least twice (with one exception). There are a couple albums that in doing my research for 2013 that I decided to give a listen to, but they left imprints on my ears too late in the game to be included. That's really about it, If I don't discuss an album from 2013 that should be on this list, you can safely assume I simply haven't come across it yet. 

Creating the list

I started by listing all the albums I could remember having listened to over the past year, and followed it up by looking up albums released in 2013 (A quick side note - Buckethead released released 33 albums in 2013! ...and I didn't listen to a single one). After compiling the list I had about 20 albums that I had listened to extensively, which doesn't seem like a ton. I probably am not really qualified to write a "top list of" like you would read on a reputable website, but we can carry on understanding the shortcomings of the rules I set.

Now that I have a list, I need to find the appropriate order. It is tempting to create some model involving metrics like number of times I listened to each album, number of sales, chart ranking, twitter mentions, Metacritic rankings, etc. Creating such a model really wouldn't get at the heart of what I really want to accomplish. While music preference is very much a personal subjective matter, I can certainly objectively say that I'd rather listen to one album over another. Of course my preference might change over time, and others will certainly have their own opinions, I hope to give a snapshot of what I connected with this past year, and what I think others might appreciate.

After compiling my list, in order to calculate rankings I first randomly ordered the albums and then created a grid with a row and corresponding column for each album. I then compared each row album to each column album and asked myself "which album would I rather listen to?" Of course if I am in a mood to dance I might choose something different than when I am feeling a bit existential, so I try to imagine that I'm in a neutral mood, and haven't listened to either album recently. Here's my grid:




Results

Ordering the data by rank results in the following ranking. We'll go with the top 10 (even if it is an arbitrary number - why not top 8 or 11? I suppose its important to support the metric system)



Two quick notes

  • I only listened to Yeezus once and included it so that every album I do like would get at least one vote. I listened to some of Kanye's other albums that are on the RS's 500 Greatest Albums, and I just didn't get them. This album in my estimation probably ranks much higher than College Dropout, but Late Registration is more listenable.
  • I guess I'm not entirely consistent, as evidenced by the several ties. For example, I have AM over both Comedown Machine and Modern Vampires of the City, both of which are over Evil Friends; yet I put Evil Friends over AM:

The Omissions

  • Paul McCartney - New  perhaps his best effort since Chaos and Creation in the Backyard, but his worst named album since Kisses on the Bottom 
  • Deerhunter - Monomania  Would have made it higher on the list if I had heard the album earlier
  • Elvis Costello and The Roots - Wise Up Ghost  Wasn't a fan, I really didn't like a lot of Costello's stuff in the RS's 500 either.
  • Many other, I'm sure

The other not top 10ers

  • Franz Ferdinand - Right Thoughts, Right Words, Right Action  The lead single might be the weakest song on the album, otherwise it is what I've come to expect from a Franz Ferdinand effort
  • Daft Punk - Random Access Memories  This was just a great album, just happens to be outside of what I usually listen to
  • New Politics - A Bad Girl in Harlem  Fun album with some very catchy tunes
  • David Bowie - The Next Day  I can't say enough about Bowie. Its no Station to Station, but a great listen
  • Deafhaven - Sunbather  This was a pretty great album for a style I don't listen to as much. Very beautiful amongst the metal. This one is definitely worth a listen
  • Pearl Jam - Lightning Bolt  The ukulele touch on some songs is nice - I enjoyed Vedder's ukulele solo album. I haven't really listened to Pearl Jam much into the aughts
  • Phoenix - Bankrupt!  Some nice tracks and still interesting
  • Dream Theater - Dream Theater  Its always a good idea to wait 12 albums before releasing an eponymous album. I really loved Octavarium and Metropolis Pt. 2: Scenes from a Memory, but haven't been as impressed with their other albums

My Top 10

10. The Flaming Lips - The Terror

The Flaming Lips are one of those bands that I would hear a song of theris here or there over the years, but I didn't really fully appreciate them until earlier this year. Yoshimi Battles the Pink Robots might be their magnum opus, but this simply is a beautiful album. Existential lyrics with haunting psychadelic landscapes reminiscent of some early Pink Floyd. This album wasn't written to release singles, but rather is a work of art as a whole.

9. My Bloody Valentine - m b v


I listened to the album Loveless as part of the RS 500 albums, and at that time I thought that it was a great album, if only I could hear through all that distortion. But what without the distortion, what would be the point? After the second track, "Only Tomorrow," I was hooked. A beautiful album that, in my opinion, surpasses its predecessor

8. Foxygen - We Are the 21st Century Ambassadors of Peace & Magic

One of those albums that I kept seeing critics praise, to which I add my own. I have listened to my fair share of The Beatles, both in and out of their experimental phase, but there really isn't a lot of psychedelic rock that gets played on classic rock/oldies stations. It wasn't until I heard more of The Kinks, Jefferson Airplane, among others, that I really gained an appreciation for that sound, and this is a great album for anyone looking to combine modern indie rock with those psychedelic influences. The influences, however, aren't limited to the San Franciscan sound, but also include the likes of The Rolling Stones and The Velvet Underground, almost as if a snapshot of those bands in the late 60s was being channeled. At times the album is humorous, at others pensive, but never lacking of interest.

7. Queens of the Stone Age - ...Like Clockwork



It took a few listens before I loved Songs for the Deaf; I enjoyed this one on the first listen. Certainly their best album since Songs for the Deaf, with the lead single "My God is the Sun," being fairly representative of what to expect from the album. I'd list one of my favorite tracks as "If I Had a Tail," which despite discussing some pretty heavy themes, I can't help but find it humorous that Alex Turner of The Arctic Monkeys appears on the track (because monkeys have tails...)

6. Arcade Fire - Reflektor


Perhaps the biggest disappointment of all albums released in 2013, if only because of the lofty expectations. Of course that is an exaggerated statement, but I was disappointed, even though it is a great album from a great band. We already had Daft Punk writing music that made us simultaneously want to ponder our existence and get down and dance, and Franz Ferdinand fills the void of indie club rock. Whatever, it isn't up to me to dictate the direction Win Butler and co. should take. I would rate Funeral as one of my all-time favorites, while Neon Bible and The Suburbs are amazing in their own right. I do love the "Black Orpheus" references of the album, and anything with David Bowie (even for just one song) isn't bad.


5. Cage the Elephant - Melophobia

I looked up this album after having heard the single "Come a Little Closer" on the radio. I did enjoy their first two efforts, but I would have placed Cage The Elephant a bit behind The Black Keys and whatever Jack White is working on. I really enjoyed the album, and have kept going back to it since the initial listen. The bookend tracks provide a perfect intro and resolution to the album, while between is full of great blues tinged alternative rock.

4. Portugal. The Man - Evil Friends

Another album that I looked up after hearing the lead single, "Purple Yellow Red and Blue." Sometimes there is just something about an album that just clicks; that you connect to on some deeper level. This was one of those albums. Danger Mouse just brings a great sound to alternative rock (psychedelic rock?), and has now produced a large number of albums that I love. Every time I listen to the album different tracks stand out, but then I realized that their song "Evil Friends" was used in a commercial currently airing, which might explain the strange desire I had the other day to visit and try their black bean and rice burritos.

3. The Strokes - Comedown Machine

Before this album came out, I read some rumors that it might be their last. It appears that may not be the case, as they are supposedly talking about doing a tour next year. The album is not held in high regard by the critics (see below); perhaps another one of those bands whose debut is transcendent or something, resulting in subsequent releases being panned if they are simply a continuation of the debut, or derided if they venture too far from what worked. The career arc of The Strokes is an interesting one, and if you were to jump from listening to Is This It? to Comedown Machine it would be quite a surprising leap indeed. I however have listened to this album countless times, and it just might be my favorite of theirs. The synthesizer worked for The Who on Who's Next, and it works here. filler, "Call It Fate, Call It Karma" is about as great of an ending an album could hope for.

 2. Arctic Monkeys - AM

The Arctic Monkeys won me over years ago, and like Arcade Fire's Reflektor I anxiously awaited its release. This album, however, did not disappoint. I love the trademark sound of The Arcitc Monkeys - not just what you tend to hear on the singles of past, but the darker sound - not unlike what you hear on the lead single "Do I Wanna Know" (or the convenient theory confirming recently released B-side "You're So Dark"). This album embraces that feel, and it simply works. Their past two albums had their moments, and though they are in my regular listening rotation, this one is on par with Favourite Worst Nightmare and  Whatever People Say I Am, That's What I'm Not. This time Metacritic agrees with my assertion:

1. Vampire Weekend - Modern Vampires of the City


Earlier this year listened to their eponymous debut quite a bit - but I didn't care as much for Contra. I think a lot of how we feel about music is a reflection of where we are in life when we first listen to it, and perhaps Contra simply did not relate well to me. Modern Vampires of the City hits the nail on the head. It not only was what I needed to hear, they removed some of the sound that I considered to be obnoxious (realizing that it was a part of their identity and was the differentiation between them and other indie rock). This is clearly a concept album with each track building on the last, yet it is still able to produce several great standalone singles. I keep coming back to this album as it never disappoints.

Final Thoughts

I do enjoy Metacritic, I think it is an interesting way of combining and weighting reviews. If there is a way to measure the consensus opinion on something, it is likely the closest you can find right now. Sometimes its also nice to stray out of the consensus and find something that is personally meaningful. If it can be both, all the better
If nothing else, it is certainly worthwhile to seek out new music. I do hope that there is something on this list that others haven't considered before that they will discover and enjoy.

Tuesday, November 5, 2013

Spider Web Plots in R

**Edit** I found a similar plotting technique using radarchart from the fmsb package, found at http://artax.karlin.mff.cuni.cz/r-help/library/fmsb/html/radarchart.html


Unless your brain works differently than mine, then polar coordinates aren't great for being precise in consuming and measuring data. Use bar charts, not pie charts, right angles! That being said, “spider plots” or “web plots” or whatever you want to call these charts, can succinctly summarize a lot of information, and are visually pleasing.

Here's a function to create this kind of plot.


webplot = function(data, data.row = NULL, y.cols = NULL, main = NULL, add = F, 
    col = "red", lty = 1, scale = T) {
    if (!is.matrix(data) & !is.data.frame(data)) 
        stop("Requires matrix or data.frame")
    if (is.null(y.cols)) 
        y.cols = colnames(data)[sapply(data, is.numeric)]
    if (sum(!sapply(data[, y.cols], is.numeric)) > 0) {
        out = paste0("\"", colnames(data)[!sapply(data, is.numeric)], "\"", 
            collapse = ", ")
        stop(paste0("All y.cols must be numeric\n", out, " are not numeric"))
    }
    if (is.null(data.row)) 
        data.row = 1
    if (is.character(data.row)) 
        if (data.row %in% rownames(data)) {
            data.row = which(rownames(data) == data.row)
        } else {
            stop("Invalid value for data.row:\nMust be a valid rownames(data) or row-index value")
        }
    if (is.null(main)) 
        main = rownames(data)[data.row]
    if (scale == T) {
        data = scale(data[, y.cols])
        data = apply(data, 2, function(x) x/max(abs(x)))
    }
    data = as.data.frame(data)
    n.y = length(y.cols)
    min.rad = 360/n.y
    polar.vals = (90 + seq(0, 360, length.out = n.y + 1)) * pi/180

    # 
    if (add == F) {
        plot(0, xlim = c(-2.2, 2.2), ylim = c(-2.2, 2.2), type = "n", axes = F, 
            xlab = "", ylab = "")
        title(main)
        lapply(polar.vals, function(x) lines(c(0, 2 * cos(x)), c(0, 2 * sin(x))))
        lapply(1:n.y, function(x) text(2.15 * cos(polar.vals[x]), 2.15 * sin(polar.vals[x]), 
            y.cols[x], cex = 0.8))

        lapply(seq(0.5, 2, 0.5), function(x) lines(x * cos(seq(0, 2 * pi, length.out = 100)), 
            x * sin(seq(0, 2 * pi, length.out = 100)), lwd = 0.5, lty = 2, col = "gray60"))
        lines(cos(seq(0, 2 * pi, length.out = 100)), sin(seq(0, 2 * pi, length.out = 100)), 
            lwd = 1.2, col = "gray50")
    }


    r = 1 + data[data.row, y.cols]
    xs = r * cos(polar.vals)
    ys = r * sin(polar.vals)
    xs = c(xs, xs[1])
    ys = c(ys, ys[1])

    lines(xs, ys, col = col, lwd = 2, lty = lty)

}

Using the mtcars data set:

webplot(mtcars)

plot of chunk f

Basically, we take a data frame, scale all numeric columns, and then plot how far above/below average (the thick black line) each of the values are for a particular row of data.

Here are the Arguments:

  • data - data.frame or matrix
  • data.row - row of data to plot (if NULL uses row 1)
  • y.cols - columns of interest (if NULL it selects all numeric columns)
  • main - title of plot (if NULL then rowname of data)
  • add - whether the plot should be added to an existing plot
  • col - color of the data line
  • lty - lty of the data line

For example, we can change the data row that we plot, as well as the columns we want to include

webplot(mtcars, 2, y.cols = c("mpg", "cyl", "disp", "hp"))

plot of chunk unnamed-chunk-2

It turns out that this isn't the easiest way to compare results, it might be helpful to overlay plots

par(mfcol = c(1, 2))
webplot(mtcars, "Mazda RX4")
webplot(mtcars, "Mazda RX4 Wag")

plot of chunk unnamed-chunk-3

par(mfcol = c(1, 1))
par(mar = c(1, 1, 2, 1))
webplot(mtcars, "Mazda RX4", main = "Compare Cars")
webplot(mtcars, "Mazda RX4 Wag", add = T, col = "blue", lty = 2)
par(new = T)
par(mar = c(0, 0, 0, 0))
plot(0, type = "n", axes = F)
legend("bottomright", lty = c(1, 2), lwd = 2, col = c("red", "blue"), c("Mazda RX4", 
    "Mazda RX4 Wag"), bty = "n")

plot of chunk unnamed-chunk-4

Which makes it easy to observe that the Mazda RX4 and Mazda RX4 Wagon are very similar, with the Wagon being a little heavier, and takes a little longer to travel a quarter mile

Thursday, September 19, 2013

Using Custom Images as "pch" values in R

In a previous post I show how one can use custom pch values to represent different data types. I've long wanted to be able to take a custom image and use that to represent the data. I recently discovered the rasterImage function in R, which allows the user to take an image and plot it! There are various examples out there of using RasterImage (such as RJournal_2011-1_Murrell.pdf), but I didn't find anything that did exactly what I wanted it to do

the tricky part is that rasterImage requires you to define the 4 boundaries of the image. The goal is then to be able to define the boundaries by only specifying an x, y coordinate, and have code smart enough to display the image with the appropriate dimensions


Here are the required packages
library(RCurl)  #for reading file from a URL
## Loading required package: bitops
library(png)  #for reading in a .png, use library(jpeg) for a .jpg
The function I wrote takes the image, the (x,y) coordinates of where you want to plot your image, and for now a cex and a pos argument. I intend on expanding the options, and hopefully will improve these functionalities over time.

image_points = function(image, x, y, cex = 1, pos = NULL) {
    if (length(x) != length(y)) {
        stop("length(x)!=length(y): check your data")
    }
    dim.x = dim(image)[2]  #image width
    dim.y = dim(image)[1]  #image height
    if (dim.x == dim.y) {
        # obtian the ratio of width to height or height to width
        ratio.x = ratio.y = 1
    } else if (dim.x < dim.y) {
        ratio.x = dim.x/dim.y
        ratio.y = 1
    } else {
        ratio.x = 1
        ratio.y = dim.y/dim.x
    }
    cex = cex/10  #how large the image should be, divided by 10 so that it matches more closely to plotting points
    pin = par()$pin  #pin provides the width and height of the _active graphic device_
    pin.ratio = pin/max(pin)  #take the ratio
    usr = par()$usr  #usr provides the lower.x, lower.y, upper.x, upper.y values of the plotable region

    # combine the active device dimensions, the image dimensions, and the
    # desired output size
    image.size.y = (usr[4] - usr[3]) * pin.ratio[1] * cex
    image.size.x = (usr[2] - usr[1]) * pin.ratio[2] * cex
    for (i in 1:length(x)) {
        # plot each point pos can be NULL (default) or 1, 2, 3, or 4, corresponding
        # to centered (defualt), bottom, left, top, right, respectively.
        if (is.null(pos)) {
            # centered at (x,y), define the bottom/top and left/right boundaries of the
            # image
            x.pos = c(x[i] - (image.size.x * ratio.x)/2, x[i] + (image.size.x * 
                ratio.x)/2)
            y.pos = c(y[i] - (image.size.y * ratio.y)/2, y[i] + (image.size.y * 
                ratio.y)/2)

            rasterImage(image, x.pos[1], y.pos[1], x.pos[2], y.pos[2])
        } else if (pos == 1) {
            x.pos = c(x[i] - (image.size.x * ratio.x)/2, x[i] + (image.size.x * 
                ratio.x)/2)
            y.pos = c(y[i] - (image.size.y * ratio.y), y[i])
        } else if (pos == 2) {
            x.pos = c(x[i] - (image.size.x * ratio.x), x[i])
            y.pos = c(y[i] - (image.size.y * ratio.y)/2, y[i] + (image.size.y * 
                ratio.y)/2)
        } else if (pos == 3) {
            x.pos = c(x[i] - (image.size.x * ratio.x)/2, x[i] + (image.size.x * 
                ratio.x)/2)
            y.pos = c(y[i], y[i] + (image.size.y * ratio.y))
        } else if (pos == 4) {
            x.pos = c(x[i], x[i] + (image.size.x * ratio.x))
            y.pos = c(y[i] - (image.size.y * ratio.y)/2, y[i] + (image.size.y * 
                ratio.y)/2)
        }

        rasterImage(image, x.pos[1], y.pos[1], x.pos[2], y.pos[2])  #plot image
    }
}
I pulled an image from sweetclipart.com using getURLContent() and readPNG()

URL = ("http://sweetclipart.com/multisite/sweetclipart/files/imagecache/middle/sports_car_2_red.png")  #where the image is located
image = readPNG(getURLContent(URL))  #gets the content of the URL
image is an array of dimensions width \( \times \) height \( \times \) channels. The first 3 channels represent the R, G, and B values (scaled 0 to 1) of each pixel, with the 4th channel representing the alpha value (scaled 0 to 1, 0 representing transparent)
Only pngs have the alpha channel, so jpegs will have 3 channels. Not all pngs have the 4th channel, if they do have the 4th channel the background won't necessarily be transparent. More on alpha values in a bit

dim(image)  #width, height, alpha
## [1] 275 550   4

Using the cars dataset we can plot the distance it took to stop by speed

data(cars)
plot(cars, type = "n", axes = F, xlab = "Speed", ylab = "Distance to Stop", 
    main = "Cars: Distance to Stop by Speed")
axis(1)
axis(2, las = 2)
x = cars$speed
y = cars$dist
image_points(image, x, y, 2)
Cars using Cars
It turns out that the data is from the 1920s, so using this image might be more appropriate:

library(jpeg)
URL2 = "http://embed.polyvoreimg.com/cgi/img-thing/size/y/tid/4985430.jpg"
image2 = readJPEG(getURLContent(URL2))
plot(cars, type = "n", axes = F, xlab = "Speed", ylab = "Distance to Stop", 
    main = "Cars: Distance to Stop by Speed\n1920's car")
axis(1)
axis(2, las = 2)
image_points(image2, x, y, 2)
Cars using Cars
Here we have a jpeg file that is a width \( \times \) height matrix with values 0 to 1 representing the black/white/gray scale. We can manipulate the data using rgb() and abind() to create an array with the appropriate R, G, B, and alpha values.
First, on this color scale, values that are closer to 1 are going to be lighter gray to white, so we can assign an alpha value of 0 (transparent) to any values that are greater than 0.8.

alpha.val = matrix(1, nrow(image2), ncol(image2))  #want a matrix of 1s (not transparent) the same size as the image
alpha.val[image2 > 0.8] = 0  #for lighter gray and white values, set alpha to 0 (transparent)
We then want to create a new array, and will set the first dimension to the original values. Because it is gray colors, R=G=B

library(abind)
image2.adj = array(image2, dim = c(nrow(image2), ncol(image2), 1))
image2.adj = abind(image2.adj, image2, image2, alpha.val)
We can then plot it:

plot(cars, type = "n", axes = F, xlab = "Speed", ylab = "Distance to Stop", 
    main = "Cars: Distance to Stop by Speed\n1920's Car w/Transparency")
axis(1)
axis(2, las = 2)
image_points(image2.adj, x, y, 2)
Cars using Cars
Notice that we have now essentially removed the border around the image, and even though the images overlap, we get a better sense of whwere the points lie.

A few final notes

  • If we want the cars to be reversed, we can simply…
image2.adj.reversed = image2.adj[, ncol(image2.adj):1, ]
plot(cars, type = "n", axes = F, xlab = "Speed", ylab = "Distance to Stop", 
    main = "Cars: Distance to Stop by Speed\n1920's car w/Transparency, Reversed")
axis(1)
axis(2, las = 2)
image_points(image2.adj.reversed, x, y, 2)
Cars using Cars
  • Using images with lower resolution will often yield better results, I don't know if there are better ways to display images at a lower resolution
  • There might be better ways to do what I've figured out here - perhaps there are some more par values that would help convert the resolution and control the cex value?