Wishful Coding

Didn't you ever wish your
computer understood you?

Female League of Legends characters

I've been putting off writing about this for a while. Looking at the whole gamer gate thing, it seems like feminism and gamers don't go together very well.

As of late I've been playing some casual League of Legends with my brother. Besides the usual gamer behaviour, I was also irked by some of the champions.

I understand that it's a fantasy game, so I'm okay with boob plate armour and I don't expect extreme realism, but to be honest some of these champs look like they walked right out of some red light district.

There are a few exceptions, but most are scarcely clad, have huge breasts and hips, and some even do pole dancing and flirting in-game.

In [79]:
from IPython.display import HTML
sexy = ['MissFortune', 'Ashe', 'Leblanc', 'Zyra', 'Evelynn', 'Janna', 'Morgana', 'Nidalee', 'Caitlyn', 'Katarina']
HTML(''.join(['<span></span><img src="img/%s_0.jpg" style="float:left;" />' % name for name in sexy]))
Out[79]:

I had the impression that their in-game roles and stats where also rather stereotypical, most of them being squishy mages.

But I can't go around saying things like that without any data to back it up, so I downloaded champion stats from the Data Dragon and loaded it into Python to do some exploration.

In [80]:
%matplotlib inline

import json
import pandas as pd
import collections

def flatten(d, parent_key='', sep='_'):
    items = []
    for k, v in d.items():
        new_key = parent_key + sep + k if parent_key else k
        if isinstance(v, collections.MutableMapping):
            items.extend(flatten(v, new_key, sep=sep).items())
        elif isinstance(v, collections.MutableSequence):
            for i, li in enumerate(v):
                items.append(("%s%s%d" % (new_key, sep, i), li))
        else:
            items.append((new_key, v))
    return dict(items)

with open("champion.json") as f:
    data = json.load(f)
    
flat = {key: flatten(value) for key, value in data.items()}
df = pd.DataFrame.from_dict(flat, orient="index")

I manually divided the champions into genders, including an 'other' gender so I don't have to argue over the gender of a cat... unless that cat is wearing a bra.

It appears that there is a pretty even divide between men, women, and monsters. Yay.

A funny thing to mention is that even though people sometimes assume every player is a 'he', often people refer to others by the gender of their champion.

In [81]:
df['gender'].value_counts().plot(kind='pie')
Out[81]:
<matplotlib.axes._subplots.AxesSubplot at 0x10d450978>

Next I looked at the average stats of the champions. Here we start to see that women in League of Legends have on average less defence and more magic than men and monsters. This makes sense, given the amount of armour they are wearing.

Women also had a slightly higher difficulty than the other genders but the difference was negligible. I removed that data to save you from bad jokes.

In [82]:
(df.groupby('gender')
 [['info_defense', 'info_attack', 'info_magic']]
 .mean()
 .plot(kind='bar')
 .legend(loc='upper center', bbox_to_anchor=(0.5, 1.2), ncol=5))
Out[82]:
<matplotlib.legend.Legend at 0x10c753ba8>

Next up are the roles champions have in-game.

There are over twice as many male tanks compared to female tanks, but both are dwarfed by the monster tanks. Fighters are also dominated by men and monsters.

On the other hand, mages and supports are primarily female. A small surprise is the large number of markswomen(ranged physical attackers).

Assassins seem to be the most equal role.

In [83]:
primary = df[['tags_0', 'gender']]
primary.columns = ['role', 'gender']
secondary = df[['tags_1', 'gender']]
secondary.columns = ['role', 'gender']
roles = pd.concat((primary, secondary))
roles.groupby(['role', 'gender']).gender.count().unstack().plot(kind='barh')
Out[83]:
<matplotlib.axes._subplots.AxesSubplot at 0x10d6fb438>

That is it for now. It was fun to experiment with Pandas and IPython notebooks. You can see the source at Github.