Category Archives: 1

Avengers, Assembled (and Visualized) – Part 2

Last week I shared a set of visualizations I made, exploring the history of The Avengers – the Marvel comic series which first appeared in 1963, and was last week released as a bombastic, blockbuster film (which, by the way, I enjoyed tremendously). I looked at the 570-issue archive as a whole, and tried to dig out some interesting patterns concerning female characters, robots, and gods (as far as I know, there are no female robot god avengers – though I guess Jocasta comes pretty close). If you missed that first post, you might want to give it a quick read right now, as I’ll be picking up where I left off.

So far, the discussion has been mostly around the characters of the Avengers, at a collective level. Lots of data is available about each individual character, as well – for example we can look at any Avenger and see every appearance they’ve made over the last 50 years. Here’s Captain America’s record number of appearances:

Captain America

And Iron Man, who’s not too far behind:

Iron Man

An my personal favourite, Hawkeye:

Hawkeye

In each of these graphics, I’ve marked the issues where the character has returned after a significant absence. We also, of course, see their first appearances (Hawkeye’s being in issue #16th, ‘The Old Order Changeth‘). You can see a pile of other Avengers’ ‘appearance maps’ in this Flickr Set – if there’s another character you’d like to see, let me know.

For the first time here we can see that we can gets some information about the individual issues past the issue number. We can look at the title, the characters who appeared in the issue, the geographic locations involved in the issue (from Alaska to the Kree homeworld), and more (the Comic Vine API offers the possibility of concepts to be linked with individual issues as well, but this information hasn’t been well-populated in the wiki).

One thing that you might have noticed from the graphics so far is that there are a lot of spikes – issues in which a lot of Avengers characters are present. The most spectacular example of these ‘party issues’ is Volume 3, #10, ‘Pomp & Pageantry”, in which a whopping 119 Avengers appeared! Here are all of these party issues since 1963:

Avengers - The Party Issues

We can see that these heaps-of-heroes issues are a pretty new phenomenon – and also that the current Avengers writer, Brian Michael Bendis, LOVES a party. He’s written lots of issues with more than 30 avengers, and even a couple with more than 50.

Which brings us nicely into a discussion about creators. So far we’ve been focused mainly on fictional characters – what about the real people that made these comic books? Like, for example, Sam Rosen, and Artie Simek:

Mr. Rosen and Mr. Simek hand-lettered all of the dialogue, and drew all of the word balloons for most of the first 50 issues of the Avengers, most often alternating back and forth, issue to issue. They’re part of a group of about 7 letterers who have been responsible for most of the Avengers typography:

Avengers CREATORS - letterer

Similarly, we can see that there are about 10 people who have been editors on the series for long stretches of time:

Avengers CREATORS - editor

You don’t see nearly this kind of consistency with pencillers:

Avengers CREATORS - penciler

Or inkers:

Avengers CREATORS - inker

I wondered after getting a look at how these creators were involved in the history of the series, if perhaps they (particularly the writers & editors) might be responsible for some of the content decisions that I examined in the last. For example, are there certain editors or writers who included more female characters in their books?

I overlaid a heat map onto the creator maps just saw above, with red stripes to indicate a high number of female characters and blue/green stripes to indicate the boys-club issues. Here are all of the editors again:

Avengers: Editors & Female Characters

And all of the writers:

Avengers: Writers & Female Characters

While it probably begs for some statistical analysis, it does seem that the gender balance gets a boost when Jim Shooter takes up the series in the early 70s. Indeed, he’s in charge during the high water mark of Avengers feminism in 1983-1984, a level which the series never gets back to.

We can see similar correlations for the numbers of gods/eternals per issue:

Avengers: Writers & Godliness

Or robots/synthezoids/androids per issue:

Avengers: Writers and Robotitude

From these we can see that while Brian Michael Bendis DOES like to party, he DOESN’T particularly like robots, and definitely isn’t a big fan of the gods.

Besides that, what have we learned from this two-part data-exploration of the Avengers? You’ve probably learned that I have too much time on my hands. I’ve learned that I really need to get my old collection out of storage and revisit some of these excellent stories. I’ve also learned that, if there’s one form of punctuation that defined the silver age of comics… it’s the ellipsis. So, to finish us off, here’s a medley of the 53 ellipsified issues in the history of Earth’s Mightiest Heroes:

(You might see a blank box here, in which case you might want to try viewing the page in Chrome).

Avengers, Assembled (and Visualized) – Part 1

This post is about comics. It’s also about superheroes, robots, Norse gods, shrinking men, and women made of light – so it makes sense that it was inspired in the first place by a 10 year-old.

Last week, I was pointed by Santiago Ortiz to this excellent chart made by Theo Zaballos, in which he plots the relative interestingness in Avengers characters from the animated series, over time. It’s a fantastic example of the power of visualization to help us understand things – or, put another way, the power of building systems to think about systems. It’s also a reminder that visualization doesn’t always need to be pitted against huge, world-changing tasks – it can be useful in exploring small, fun, even seemingly frivolous things.

I started reading comics in 1985 (coincidentally, when I was 10). For years, I’d visit the comic shop every Wednesday, and pick up a stack of titles – and The Avengers was a real mainstay on my list. I was always more of a reader than a collector; my longboxes were full of dog-eared issues from incomplete series, which I revisited over and over again until the stories imprinted themselves in my brain.

There’s a huge storehouse of mythology, cultural touchstones, and real historical events contained in the pages of the 570 issues of the Avengers.

Inspired by Theo, and using comicvine.com’s API, I’ve put together a few datasets and some tools that I can use to visually explore some of this leotarded history.

The Avengers has been published pretty much continuously since 1963. Here are the covers of all 570 issues:

Every Issue of the Avengers

Now, you might be aware of a little, low budget art-house movie that’s being released tomorrow about this particular group of costumed heroes. That movie features 5 avengers – Captain America, Iron Man, Thor, Hawkeye, and Black Widow. But did you know there were 127 more Avengers? You may know that the Avengers were created by Stan Lee and Jack Kirby, but you might be surprised to hear that there were 184 other people who invented Avengers characters. In total, there have been 581 men and women who written, edited, pencilled, inked, colored, lettered, and otherwise created at least one issue of the Avengers.

Let’s start with a look at those characters. My first thought was to use images of the characters in my visualizations, but while the Comic Vine API provides images in all kinds of sizes, the styles of drawing are so varied that it ended up not holding together. Instead, then, I built a small tool that let me go through those characters and pick three colours that I thought represented them the best (everybody gets a shield!). Here are all of the Avengers in an overlapped plot that doesn’t really tell us much, but gives you an idea of what these icons look like:

Avengers20_54_41

These character icons can be drawn at any size, and give us a nice way to plot the characters that isn’t just dots or boxes. Here’s all of the Avengers again, this time plotted by their number of appearances:

Avengers21_12_42

Below Captain America is a cluster of the most consistent Avengers – Iron Man, Vision, Scarlet Witch, Thor, Hawkeye, Wasp, and Henry Pym (aka Ant Man). That blue and grey dot trailing just behind is Jarvis, the Avengers’ butler – who also happens to be an honorary member of the team.

Using those same shield icons, but sorting by issue so that characters in an issue together form a radial line, here is every appearance of ever Avengers character in every issue:

Every Avenger.

It’s not too helpful, but we can use this same system, and filter it by any number of criteria. For example, let’s look at just first appearances of Avengers:

First Appearances

You can see the same graphic in a timeline form here:

First Appearances - Timeline

I built a little tool to let me assign three colours to each Avenger, so they’re all represented by small spheres (now would be a good time to look at the full resolution version of that image – a good strategy for everything I’m going to put in this post) We can see a big cluster of major Avengers appearing in the first few episodes, with some other big names coming in the next few years (Vision, the Avenger with the 3rd most appearances in issues, doesn’t come along until #57). While there are a couple of major additions along the way (She-Hulk & Photon in 1982), we can see that the cast of characters for the team is defined pretty early.

One of the first things that I was interested in was the gender balance in the Avengers over time. While there have been women on the team since the beginning (Janet Van Dyne, aka The Wasp, appears in issue #1), has this changed or increased over the 50 year span of the series?

Let’s have a look:

Female Avengers Characters

Female Characters - Timeline

You’ll notice that the Wasp (in yellow), and the Scarlet Witch (in red), pretty much hold the fort for the female Avengers until the late 70s, at which time variety and frequency of female characters increases. There are some dips – 1990 to 1992, and 2005 to 2007, and overall the female ratio at the Avengers mansion peaks in the 1980s and never quite gets back up to that level again.

Of course, there are many other categorizations of comic characters that we can make aside from gender. I mentioned Vision before, who is a robot (OK, OK, he’s a synthezoid). How have superheroes of the electronic persuasion fared amongst Earth’s Mightiest Heroes?

I’m glad you asked:

The Robots

Here we see some much more interesting patterns. Robots are big from the late 60s to the early 1990s, after which they disappear. There’s a robot renaissance of sorts from 1990 to 2005, but again they lose density (see what I did there, Avengers fans?).

We can do the same thing with Gods, and Eternals (if you don’t know the difference, ask your local comic shop clerk):

The Gods

Gods & Eternals - Timeline

Again, there is some real patchiness here. Now, the clever ones among you might be wondering if these patterns are tied to historical periods, or if they are linked to the preferences of specific writers, editors, or artists. Is that crowded patch of Gods in 1985 due to a cultural fascination with myth? Or do Mark Gruenwald & Jim shooter just really, really like Thor? Great questions, and ones that I’ll take a look at Part 2 of this post.

This week-long dig through Avengers data has been fascinating. Even as an Avengers fan, it’s been surprising to see the depth and richness of content that finds its way into the pages of every issue and volume. As I’ve been working, I’ve also been reading a lot about the various people – inkers, letterers, writers, who have built the Avengers story over time. It has been a good reminder, particularly in the wake of a blockbuster film, that myths are rarely formed by individuals.

Finally, it should give anyone fearing a shortage of Avengers storylines and characters for possible sequels some reassurance – 5 down, 127 to go. (Mr. Whedon, if you’re looking for a researcher, you know where to find me.)

‘Nuff said. (For now.)

TEDxVancouver: The Weight of Data

In November, I was asked to come back to my hometown and give a talk at TEDxVancouver. The overarching theme of the event was ‘The Frontier’ – along with me, there would be talking about space, deep-sea science, and spiritual exploration. I decided to frame my talk around what I consider to be a largely un-explored part of the big data conversation that has opened up over the last few years: thinking about data in a human context. I talk a bit about my history with HyperCard, rattle over a series of data-based projects, and end with a call-to-arms for artists, poets, writers and other creatives to join the discourse around data.

I won’t give the whole talk away, since you can watch it for yourself below. As always, I’d love to hear feedback/questions/ridicule – you can leave a comment below, or join in on this already feisty thread on Google+.

Selected Works (2009 – 2011)

These days my spare time is typically measured in seconds – so I took advantage of a rare free morning today to put together a very simple list of the some of the work that I have built since the beginning of 2009. You can find a link to this list at the top of the site – or you can just click here. As always, comments and suggestions are encouraged and appreciated.

UPDATED: Quick Tutorial – Processing & Twitter

** Since I first released this tutorial in 2009, it has received thousands of views and has hopefully helped some of you get started with building projects incorporating Twitter with Processing. In late 2010, Twitter changed the way that authorization works, so I’ve updated the tutorial to get it inline with the new Twitter API functionality.

Accessing information from the Twitter API with Processing is (reasonably) easy. A few people have sent me e-mails asking how it all works, so I thought I’d write a very quick tutorial to get everyone up on their feet.

We don’t need to know too much about how the Twitter API functions, because someone has put together a very useful Java library to do all of the dirty work for us. It’s called twitter4j, and you can download it here. We’ll be using this in the first step of the building section of this tutorial.

1. Authentication

Here’s the tricky part. In the olden days, Twitter used to be happy with us sending it a username and password pair for authentication. Now, all of the Twitter API functionality uses an oAuth system, which allows people to authenticate applications through a login at twitter.com (so that developers never see the user’s login information).

That’s pretty good from a security standpoint, but it makes our job a little bit harder. Now, instead of just needing a short username and password, we need FOUR things to authenticate our sketch: A consumer key & secret, and an access token & secret. You can get all 4 of these things from the twitter developer page.

1. Visit https://dev.twitter.com/ and login with your twitter username and password
2. Click on the ‘Create an app’ button at the bottom right
3. Fill out the form that follows – you can use temporary values (like “Jer’s awesome test application”) for the first three fields.
4. Once you’ve agreed to the developer terms, you’ll arrive at a page which shows the first two of the four things that we need: the Consumer key and the Consumer secret. Copy and paste these somewhere so you have them ready to access.

5. To get the other two values that we need, click on the button that says ‘Recreate my access token’. Copy and paste those two values (Access token and Access token secret) so that we have all four in the same place.

2. Building

1. Open up a new Processing sketch.
2. Import the twitter4j library. In your downloaded twitter4j files, you’ll find the core .jar in a directory called ‘lib’. You’re looking for a file called something like ‘twitter4j-core-2.2.5.jar’. We can add this to our sketch by simply dragging the twitter4j-core-2.2.5.jar file onto your sketch window. If you want to check, you should now see this file in your sketch folder, inside of a new ‘code’ directory.
3. The first thing we’ll do in our new file is to store the credentials that we gathered in the first part of this tutorial into a ConfigurationBuilder object (this is a built-in part of the twitter4j library):

** Don’t use the credentials below – these are fake ones that I made up – use the ones that you copy & pasted in steps 4 & 5 above

ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("lPFSpjBppo5u4KI5xEXaQ");
cb.setOAuthConsumerSecret("SYt3e4xxSHUL1gPfM9bxQIq6Jf34Hln9T1q9KGCPs");
cb.setOAuthAccessToken("17049577-Yyo3AEVsqZZopPTr055TFdySop228pKKAZGbJDtnV");
cb.setOAuthAccessTokenSecret("6ZjJBebElMBiOOeyVeh8GFLsROtXXtKktXALxAT0I");

4. Now we’ll make the main Twitter object that we can use to do pretty much anything you can do on the twitter website – get status updates, run search queries, find follower information, etc. This Twitter object gets built by something called the TwitterFactory, which needs our configuration information that we set above:

ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("lPFSpjBppo5u4KI5xEXaQ");
cb.setOAuthConsumerSecret("SYt3e4xxSHUL1gPfM9bxQIq6Jf34Hln9T1q9KGCPs");
cb.setOAuthAccessToken("17049577-Yyo3AEVsqZZopPTr055TFdySop228pKKAZGbJDtnV");
cb.setOAuthAccessTokenSecret("6ZjJBebElMBiOOeyVeh8GFLsROtXXtKktXALxAT0I");

Twitter twitter = new TwitterFactory(cb.build()).getInstance();

5. Now that we have a Twitter object, we want to build a query to search via the Twitter API for a specific term or phrase. This is code that will not always work – sometimes the Twitter API might be down, or our search might not return any results, or we might not be connected to the internet. The Twitter object in twitter4j handles those types of conditions by throwing back an exception to us; we need to have a try/catch structure ready to deal with that if it happens:

ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("lPFSpjBppo5u4KI5xEXaQ");
cb.setOAuthConsumerSecret("SYt3e4xxSHUL1gPfM9bxQIq6Jf34Hln9T1q9KGCPs");
cb.setOAuthAccessToken("17049577-Yyo3AEVsqZZopPTr055TFdySop228pKKAZGbJDtnV");
cb.setOAuthAccessTokenSecret("6ZjJBebElMBiOOeyVeh8GFLsROtXXtKktXALxAT0I");

Twitter twitter = new TwitterFactory(cb.build()).getInstance();
Query query = new Query("#OWS");

try {
  QueryResult result = twitter.search(query);
}
catch (TwitterException te) {
  println("Couldn't connect: " + te);
};

5. This code is working – but we haven’t done anything with the results. Here, we’ll set the results per page parameter for the query to 100 to get the last 100 results with the term ‘#OWS’ and spit those results into the output panel:


ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("lPFSpjBppo5u4KI5xEXaQ");
cb.setOAuthConsumerSecret("SYt3e4xxSHUL1gPfM9bxQIq6Jf34Hln9T1q9KGCPs");
cb.setOAuthAccessToken("17049577-Yyo3AEVsqZZopPTr055TFdySop228pKKAZGbJDtnV");
cb.setOAuthAccessTokenSecret("6ZjJBebElMBiOOeyVeh8GFLsROtXXtKktXALxAT0I");

Twitter twitter = new TwitterFactory(cb.build()).getInstance();
Query query = new Query("#OWS");
query.setRpp(100);

try {
  QueryResult result = twitter.search(query);
  ArrayList tweets = (ArrayList) result.getTweets();

  for (int i = 0; i < tweets.size(); i++) {
    Tweet t = (Tweet) tweets.get(i);
    String user = t.getFromUser();
    String msg = t.getText();
    Date d = t.getCreatedAt();
    println("Tweet by " + user + " at " + d + ": " + msg);
  };
}
catch (TwitterException te) {
  println("Couldn't connect: " + te);
};

It seems stupid to come all of this way without doing something visual, so let’s throw all of the words that we see in the tweets onto the screen, quick and dirty, at random positions. The following code takes our existing instructions and puts them into the standard Processing setup/draw enclosures so that we can do some animation over time:


//Build an ArrayList to hold all of the words that we get from the imported tweets
ArrayList<String> words = new ArrayList();

void setup() {
  //Set the size of the stage, and the background to black.
  size(550,550);
  background(0);
  smooth();
 
  //Credentials
  ConfigurationBuilder cb = new ConfigurationBuilder();
  cb.setOAuthConsumerKey("lPFSpjBppo5u4KI5xEXaQ");
  cb.setOAuthConsumerSecret("SYt3e4xxSHUL1gPfM9bxQIq6Jf34Hln9T1q9KGCPs");
  cb.setOAuthAccessToken("17049577-Yyo3AEVsqZZopPTr055TFdySop228pKKAZGbJDtnV");
  cb.setOAuthAccessTokenSecret("6ZjJBebElMBiOOeyVeh8GFLsROtXXtKktXALxAT0I");

  //Make the twitter object and prepare the query
  Twitter twitter = new TwitterFactory(cb.build()).getInstance();
  Query query = new Query("#OWS");
  query.setRpp(100);

  //Try making the query request.
  try {
    QueryResult result = twitter.search(query);
    ArrayList tweets = (ArrayList) result.getTweets();

    for (int i = 0; i < tweets.size(); i++) {
      Tweet t = (Tweet) tweets.get(i);
      String user = t.getFromUser();
      String msg = t.getText();
      Date d = t.getCreatedAt();
      println("Tweet by " + user + " at " + d + ": " + msg);
      
      //Break the tweet into words
      String[] input = msg.split(" ");
      for (int j = 0;  j < input.length; j++) {
       //Put each word into the words ArrayList
       words.add(input[j]);
      }
    };
  }
  catch (TwitterException te) {
    println("Couldn't connect: " + te);
  };
}

void draw() {
  //Draw a faint black rectangle over what is currently on the stage so it fades over time.
  fill(0,1);
  rect(0,0,width,height);
  
  //Draw a word from the list of words that we've built
  int i = (frameCount % words.size());
  String word = words.get(i);
  
  //Put it somewhere random on the stage, with a random size and colour
  fill(255,random(50,150));
  textSize(random(10,30));
  text(word, random(width), random(height));
}


** Extra-coolness: see this example working in the browser with Processing.js!!

That’s it! This example is very simple, but it’s the bare bones of what you need build a project which connects Twitter through Processing.

Shortly I’ll add another post which shows how to use Processing with the Twitter Streaming API, so that we can deal with large volumes of tweets over time.

Good luck!