July 25, 2013

While discussing League of Legends with a friend, we both remarked that it felt like most support-oriented champions are female. This seemed mildly amusing, so I decided to check out the data.

First lets just load up some pre-massaged data about all the current Champions in the game. For those unfamiliar with League, there are about 100 different characters you can play, called Champions. I went though the whole list and assigned a gender based on gender-specific pronouns in the skill descriptions and backstory for each Champion.

import requests
from collections import defaultdict
from pylab import *
champs = requests.get('https://coderanger.net/champions.json').json

Overall

Our first graph is simple a comparison of the total number of each gender. While this isn't perfectly balanced, it is much closer than most games, and definitely respectable at least.

gender_totals = defaultdict(int)
for champ in champs.itervalues():
    gender_totals[champ['gender']] += 1

figure(figsize=(6,6))
pie([gender_totals['male'], gender_totals['female']], labels=['Male %s'%gender_totals['male'], 'Female %s'%gender_totals['female']], colors=['lightcyan', 'pink'], startangle=90, autopct='%0.2f%%')
show()

By Attribute

Next lets look at the breakdown by each attribute. These are the official Riot-specified tags on each Champion. As you can see, it is indeed the case that support Champions are generally female, with melee and tank characters being quite male dominated.

per_attribute = defaultdict(lambda: defaultdict(int))
for champ in champs.itervalues():
    for attr in champ['attributes']:
        per_attribute[attr][champ['gender']] += 1

figure(figsize=(10,10))
ind = np.arange(len(per_attribute))
width = 0.4
rects_m = bar(0, width, [v['male'] for v in per_attribute.itervalues()], ind+width, color='lightcyan', orientation='horizontal')
rects_f = bar(0, width, [v['female'] for v in per_attribute.itervalues()], ind, color='pink', orientation='horizontal')
yticks(ind+width, per_attribute.keys() )

def autolabel(rects):
    # attach some text labels
    for rect in rects:
        width = rect.get_width()
        plt.text(width+1, rect.get_y()+rect.get_height()/2.0, str(width),
                ha='left', va='center')
autolabel(rects_m)
autolabel(rects_f)

show()

By Type

And finally using the Champion type as determined by the weekly free rotation. This mostly mirrors the graph above, showing an even heavier female bias on support, male bias on close-range, and roughly equal on long-range.

per_type = defaultdict(lambda: defaultdict(int))
for champ in champs.itervalues():
    per_type[champ['type']][champ['gender']] += 1

figure(figsize=(10,10))
ind = np.arange(len(per_type))
width = 0.4
rects_m = bar(0, width, [v['male'] for v in per_type.itervalues()], ind+width, color='lightcyan', orientation='horizontal')
rects_f = bar(0, width, [v['female'] for v in per_type.itervalues()], ind, color='pink', orientation='horizontal')
yticks(ind+width, per_type.keys() )
autolabel(rects_m)
autolabel(rects_f)

show()

Conclusions

What to make of all this? I'm honestly not quite sure. I would definitely say there is an aspect of traditional gender roles in play, women as healers, men as brawlers. That isn't automatically a bad thing, but perhaps this shows Riot could stand to make a few more stereotype-defying characters here and there.