Video Game Publishers and Genres with Split Chord
Video Game Titles - Publishers and Genres
Preamble
import numpy as np # for multi-dimensional containers
import pandas as pd # for DataFrames
import itertools
from plotapi import SplitChord, Chord
Introduction
The Dataset
The dataset documentation states that we can expect 13 variables per each of the 1017 Pokémon of the first eight generations.
Let's download the mirrored dataset and have a look for ourselves.
data = pd.read_csv('gummy.csv',index_col=0)
data.head()
data.dtypes
Haribo int64 Sweet Smiles int64 Lolli&Pops int64 Tooty Fruity int64 Herbert's Best int64 HEB int64 Lily's Sweet Fruity int64 Albanese int64 Organic Tiny int64 Kroger int64 Albanese Tropical int64 Black Forest int64 dtype: object
capitalise the name, personality, and species of each villager.
It looks good so far, but let's confirm the 13 variables against 1017 samples from the documentation.
data = 13-data
data.sum()
Haribo 128 Sweet Smiles 162 Lolli&Pops 86 Tooty Fruity 104 Herbert's Best 64 HEB 174 Lily's Sweet Fruity 59 Albanese 172 Organic Tiny 112 Kroger 150 Albanese Tropical 98 Black Forest 96 dtype: int64
Perfect, that's exactly what we were expecting.
Data Wrangling
We need to do a bit of data wrangling before we can visualise our data. We can see from the columns names that the Pokémon types are split between the columns Type 1
and Type 2
.
So let's select just these two columns and work with a list containing only them as we move forward.
Now for the names of our types.
Which we can now use to create the matrix.
Chord Diagram
Time to visualise the co-occurrence of types using a chord diagram. We are going to use a list of custom colours that represent the types.
#right = data.columns.to_list()
right = data.sum(numeric_only=True, axis=0).sort_values(ascending=False).index.to_list()
left = data.index.to_list()
nodes = []
for node in left:
nodes.append({"name":node, "group":"left"})
for node in right:
nodes.append({"name":node, "group":"right"})
nodes
[{'name': 'Ben', 'group': 'left'}, {'name': 'Holly', 'group': 'left'}, {'name': 'Andy', 'group': 'left'}, {'name': 'Gretchen', 'group': 'left'}, {'name': 'Matt', 'group': 'left'}, {'name': 'Gary', 'group': 'left'}, {'name': 'Becca', 'group': 'left'}, {'name': 'Ashley', 'group': 'left'}, {'name': 'John', 'group': 'left'}, {'name': 'Gina', 'group': 'left'}, {'name': 'Aaron', 'group': 'left'}, {'name': 'Natalie', 'group': 'left'}, {'name': 'Justin', 'group': 'left'}, {'name': 'Liv', 'group': 'left'}, {'name': 'Dave', 'group': 'left'}, {'name': 'Allyson', 'group': 'left'}, {'name': 'Ricky', 'group': 'left'}, {'name': 'Luis', 'group': 'left'}, {'name': 'HEB ', 'group': 'right'}, {'name': 'Albanese', 'group': 'right'}, {'name': 'Sweet Smiles', 'group': 'right'}, {'name': 'Kroger', 'group': 'right'}, {'name': 'Haribo', 'group': 'right'}, {'name': 'Organic Tiny', 'group': 'right'}, {'name': 'Tooty Fruity', 'group': 'right'}, {'name': 'Albanese Tropical', 'group': 'right'}, {'name': 'Black Forest', 'group': 'right'}, {'name': 'Lolli&Pops', 'group': 'right'}, {'name': "Herbert's Best", 'group': 'right'}, {'name': "Lily's Sweet Fruity", 'group': 'right'}]
columns = data.columns.tolist()
links = []
for n, i in data.iterrows():
for c in columns:
links.append({"source": n,
"target": c,
"value": int(i[c])})
links
[{'source': 'Ben', 'target': 'Haribo', 'value': 12}, {'source': 'Ben', 'target': 'Sweet Smiles', 'value': 8}, {'source': 'Ben', 'target': 'Lolli&Pops', 'value': 2}, {'source': 'Ben', 'target': 'Tooty Fruity', 'value': 6}, {'source': 'Ben', 'target': "Herbert's Best", 'value': 1}, {'source': 'Ben', 'target': 'HEB ', 'value': 9}, {'source': 'Ben', 'target': "Lily's Sweet Fruity", 'value': 3}, {'source': 'Ben', 'target': 'Albanese', 'value': 10}, {'source': 'Ben', 'target': 'Organic Tiny', 'value': 4}, {'source': 'Ben', 'target': 'Kroger', 'value': 10}, {'source': 'Ben', 'target': 'Albanese Tropical', 'value': 5}, {'source': 'Ben', 'target': 'Black Forest', 'value': 7}, {'source': 'Holly', 'target': 'Haribo', 'value': 7}, {'source': 'Holly', 'target': 'Sweet Smiles', 'value': 10}, {'source': 'Holly', 'target': 'Lolli&Pops', 'value': 4}, {'source': 'Holly', 'target': 'Tooty Fruity', 'value': 6}, {'source': 'Holly', 'target': "Herbert's Best", 'value': 3}, {'source': 'Holly', 'target': 'HEB ', 'value': 9}, {'source': 'Holly', 'target': "Lily's Sweet Fruity", 'value': 1}, {'source': 'Holly', 'target': 'Albanese', 'value': 12}, {'source': 'Holly', 'target': 'Organic Tiny', 'value': 11}, {'source': 'Holly', 'target': 'Kroger', 'value': 8}, {'source': 'Holly', 'target': 'Albanese Tropical', 'value': 2}, {'source': 'Holly', 'target': 'Black Forest', 'value': 5}, {'source': 'Andy', 'target': 'Haribo', 'value': 12}, {'source': 'Andy', 'target': 'Sweet Smiles', 'value': 10}, {'source': 'Andy', 'target': 'Lolli&Pops', 'value': 1}, {'source': 'Andy', 'target': 'Tooty Fruity', 'value': 4}, {'source': 'Andy', 'target': "Herbert's Best", 'value': 5}, {'source': 'Andy', 'target': 'HEB ', 'value': 6}, {'source': 'Andy', 'target': "Lily's Sweet Fruity", 'value': 2}, {'source': 'Andy', 'target': 'Albanese', 'value': 11}, {'source': 'Andy', 'target': 'Organic Tiny', 'value': 3}, {'source': 'Andy', 'target': 'Kroger', 'value': 7}, {'source': 'Andy', 'target': 'Albanese Tropical', 'value': 9}, {'source': 'Andy', 'target': 'Black Forest', 'value': 8}, {'source': 'Gretchen', 'target': 'Haribo', 'value': 2}, {'source': 'Gretchen', 'target': 'Sweet Smiles', 'value': 10}, {'source': 'Gretchen', 'target': 'Lolli&Pops', 'value': 6}, {'source': 'Gretchen', 'target': 'Tooty Fruity', 'value': 4}, {'source': 'Gretchen', 'target': "Herbert's Best", 'value': 3}, {'source': 'Gretchen', 'target': 'HEB ', 'value': 12}, {'source': 'Gretchen', 'target': "Lily's Sweet Fruity", 'value': 1}, {'source': 'Gretchen', 'target': 'Albanese', 'value': 11}, {'source': 'Gretchen', 'target': 'Organic Tiny', 'value': 9}, {'source': 'Gretchen', 'target': 'Kroger', 'value': 7}, {'source': 'Gretchen', 'target': 'Albanese Tropical', 'value': 5}, {'source': 'Gretchen', 'target': 'Black Forest', 'value': 8}, {'source': 'Matt', 'target': 'Haribo', 'value': 12}, {'source': 'Matt', 'target': 'Sweet Smiles', 'value': 8}, {'source': 'Matt', 'target': 'Lolli&Pops', 'value': 2}, {'source': 'Matt', 'target': 'Tooty Fruity', 'value': 6}, {'source': 'Matt', 'target': "Herbert's Best", 'value': 1}, {'source': 'Matt', 'target': 'HEB ', 'value': 9}, {'source': 'Matt', 'target': "Lily's Sweet Fruity", 'value': 3}, {'source': 'Matt', 'target': 'Albanese', 'value': 10}, {'source': 'Matt', 'target': 'Organic Tiny', 'value': 4}, {'source': 'Matt', 'target': 'Kroger', 'value': 10}, {'source': 'Matt', 'target': 'Albanese Tropical', 'value': 5}, {'source': 'Matt', 'target': 'Black Forest', 'value': 7}, {'source': 'Gary', 'target': 'Haribo', 'value': 12}, {'source': 'Gary', 'target': 'Sweet Smiles', 'value': 11}, {'source': 'Gary', 'target': 'Lolli&Pops', 'value': 7}, {'source': 'Gary', 'target': 'Tooty Fruity', 'value': 8}, {'source': 'Gary', 'target': "Herbert's Best", 'value': 4}, {'source': 'Gary', 'target': 'HEB ', 'value': 10}, {'source': 'Gary', 'target': "Lily's Sweet Fruity", 'value': 1}, {'source': 'Gary', 'target': 'Albanese', 'value': 5}, {'source': 'Gary', 'target': 'Organic Tiny', 'value': 9}, {'source': 'Gary', 'target': 'Kroger', 'value': 6}, {'source': 'Gary', 'target': 'Albanese Tropical', 'value': 3}, {'source': 'Gary', 'target': 'Black Forest', 'value': 2}, {'source': 'Becca', 'target': 'Haribo', 'value': 3}, {'source': 'Becca', 'target': 'Sweet Smiles', 'value': 10}, {'source': 'Becca', 'target': 'Lolli&Pops', 'value': 6}, {'source': 'Becca', 'target': 'Tooty Fruity', 'value': 4}, {'source': 'Becca', 'target': "Herbert's Best", 'value': 2}, {'source': 'Becca', 'target': 'HEB ', 'value': 11}, {'source': 'Becca', 'target': "Lily's Sweet Fruity", 'value': 1}, {'source': 'Becca', 'target': 'Albanese', 'value': 12}, {'source': 'Becca', 'target': 'Organic Tiny', 'value': 8}, {'source': 'Becca', 'target': 'Kroger', 'value': 5}, {'source': 'Becca', 'target': 'Albanese Tropical', 'value': 9}, {'source': 'Becca', 'target': 'Black Forest', 'value': 7}, {'source': 'Ashley', 'target': 'Haribo', 'value': 12}, {'source': 'Ashley', 'target': 'Sweet Smiles', 'value': 2}, {'source': 'Ashley', 'target': 'Lolli&Pops', 'value': 4}, {'source': 'Ashley', 'target': 'Tooty Fruity', 'value': 10}, {'source': 'Ashley', 'target': "Herbert's Best", 'value': 1}, {'source': 'Ashley', 'target': 'HEB ', 'value': 5}, {'source': 'Ashley', 'target': "Lily's Sweet Fruity", 'value': 8}, {'source': 'Ashley', 'target': 'Albanese', 'value': 11}, {'source': 'Ashley', 'target': 'Organic Tiny', 'value': 9}, {'source': 'Ashley', 'target': 'Kroger', 'value': 5}, {'source': 'Ashley', 'target': 'Albanese Tropical', 'value': 3}, {'source': 'Ashley', 'target': 'Black Forest', 'value': 6}, {'source': 'John', 'target': 'Haribo', 'value': 2}, {'source': 'John', 'target': 'Sweet Smiles', 'value': 11}, {'source': 'John', 'target': 'Lolli&Pops', 'value': 6}, {'source': 'John', 'target': 'Tooty Fruity', 'value': 9}, {'source': 'John', 'target': "Herbert's Best", 'value': 1}, {'source': 'John', 'target': 'HEB ', 'value': 12}, {'source': 'John', 'target': "Lily's Sweet Fruity", 'value': 5}, {'source': 'John', 'target': 'Albanese', 'value': 8}, {'source': 'John', 'target': 'Organic Tiny', 'value': 3}, {'source': 'John', 'target': 'Kroger', 'value': 10}, {'source': 'John', 'target': 'Albanese Tropical', 'value': 7}, {'source': 'John', 'target': 'Black Forest', 'value': 4}, {'source': 'Gina', 'target': 'Haribo', 'value': 3}, {'source': 'Gina', 'target': 'Sweet Smiles', 'value': 12}, {'source': 'Gina', 'target': 'Lolli&Pops', 'value': 5}, {'source': 'Gina', 'target': 'Tooty Fruity', 'value': 4}, {'source': 'Gina', 'target': "Herbert's Best", 'value': 2}, {'source': 'Gina', 'target': 'HEB ', 'value': 11}, {'source': 'Gina', 'target': "Lily's Sweet Fruity", 'value': 1}, {'source': 'Gina', 'target': 'Albanese', 'value': 7}, {'source': 'Gina', 'target': 'Organic Tiny', 'value': 10}, {'source': 'Gina', 'target': 'Kroger', 'value': 6}, {'source': 'Gina', 'target': 'Albanese Tropical', 'value': 9}, {'source': 'Gina', 'target': 'Black Forest', 'value': 8}, {'source': 'Aaron', 'target': 'Haribo', 'value': 11}, {'source': 'Aaron', 'target': 'Sweet Smiles', 'value': 9}, {'source': 'Aaron', 'target': 'Lolli&Pops', 'value': 7}, {'source': 'Aaron', 'target': 'Tooty Fruity', 'value': 10}, {'source': 'Aaron', 'target': "Herbert's Best", 'value': 4}, {'source': 'Aaron', 'target': 'HEB ', 'value': 8}, {'source': 'Aaron', 'target': "Lily's Sweet Fruity", 'value': 3}, {'source': 'Aaron', 'target': 'Albanese', 'value': 10}, {'source': 'Aaron', 'target': 'Organic Tiny', 'value': 1}, {'source': 'Aaron', 'target': 'Kroger', 'value': 12}, {'source': 'Aaron', 'target': 'Albanese Tropical', 'value': 5}, {'source': 'Aaron', 'target': 'Black Forest', 'value': 2}, {'source': 'Natalie', 'target': 'Haribo', 'value': 2}, {'source': 'Natalie', 'target': 'Sweet Smiles', 'value': 12}, {'source': 'Natalie', 'target': 'Lolli&Pops', 'value': 8}, {'source': 'Natalie', 'target': 'Tooty Fruity', 'value': 5}, {'source': 'Natalie', 'target': "Herbert's Best", 'value': 6}, {'source': 'Natalie', 'target': 'HEB ', 'value': 9}, {'source': 'Natalie', 'target': "Lily's Sweet Fruity", 'value': 7}, {'source': 'Natalie', 'target': 'Albanese', 'value': 10}, {'source': 'Natalie', 'target': 'Organic Tiny', 'value': 4}, {'source': 'Natalie', 'target': 'Kroger', 'value': 11}, {'source': 'Natalie', 'target': 'Albanese Tropical', 'value': 1}, {'source': 'Natalie', 'target': 'Black Forest', 'value': 3}, {'source': 'Justin', 'target': 'Haribo', 'value': 1}, {'source': 'Justin', 'target': 'Sweet Smiles', 'value': 8}, {'source': 'Justin', 'target': 'Lolli&Pops', 'value': 5}, {'source': 'Justin', 'target': 'Tooty Fruity', 'value': 4}, {'source': 'Justin', 'target': "Herbert's Best", 'value': 10}, {'source': 'Justin', 'target': 'HEB ', 'value': 12}, {'source': 'Justin', 'target': "Lily's Sweet Fruity", 'value': 2}, {'source': 'Justin', 'target': 'Albanese', 'value': 11}, {'source': 'Justin', 'target': 'Organic Tiny', 'value': 3}, {'source': 'Justin', 'target': 'Kroger', 'value': 9}, {'source': 'Justin', 'target': 'Albanese Tropical', 'value': 7}, {'source': 'Justin', 'target': 'Black Forest', 'value': 6}, {'source': 'Liv', 'target': 'Haribo', 'value': 12}, {'source': 'Liv', 'target': 'Sweet Smiles', 'value': 10}, {'source': 'Liv', 'target': 'Lolli&Pops', 'value': 6}, {'source': 'Liv', 'target': 'Tooty Fruity', 'value': 7}, {'source': 'Liv', 'target': "Herbert's Best", 'value': 5}, {'source': 'Liv', 'target': 'HEB ', 'value': 8}, {'source': 'Liv', 'target': "Lily's Sweet Fruity", 'value': 3}, {'source': 'Liv', 'target': 'Albanese', 'value': 9}, {'source': 'Liv', 'target': 'Organic Tiny', 'value': 1}, {'source': 'Liv', 'target': 'Kroger', 'value': 11}, {'source': 'Liv', 'target': 'Albanese Tropical', 'value': 2}, {'source': 'Liv', 'target': 'Black Forest', 'value': 4}, {'source': 'Dave', 'target': 'Haribo', 'value': 10}, {'source': 'Dave', 'target': 'Sweet Smiles', 'value': 7}, {'source': 'Dave', 'target': 'Lolli&Pops', 'value': 8}, {'source': 'Dave', 'target': 'Tooty Fruity', 'value': 1}, {'source': 'Dave', 'target': "Herbert's Best", 'value': 4}, {'source': 'Dave', 'target': 'HEB ', 'value': 12}, {'source': 'Dave', 'target': "Lily's Sweet Fruity", 'value': 2}, {'source': 'Dave', 'target': 'Albanese', 'value': 9}, {'source': 'Dave', 'target': 'Organic Tiny', 'value': 7}, {'source': 'Dave', 'target': 'Kroger', 'value': 11}, {'source': 'Dave', 'target': 'Albanese Tropical', 'value': 5}, {'source': 'Dave', 'target': 'Black Forest', 'value': 3}, {'source': 'Allyson', 'target': 'Haribo', 'value': 8}, {'source': 'Allyson', 'target': 'Sweet Smiles', 'value': 11}, {'source': 'Allyson', 'target': 'Lolli&Pops', 'value': 3}, {'source': 'Allyson', 'target': 'Tooty Fruity', 'value': 2}, {'source': 'Allyson', 'target': "Herbert's Best", 'value': 5}, {'source': 'Allyson', 'target': 'HEB ', 'value': 12}, {'source': 'Allyson', 'target': "Lily's Sweet Fruity", 'value': 4}, {'source': 'Allyson', 'target': 'Albanese', 'value': 10}, {'source': 'Allyson', 'target': 'Organic Tiny', 'value': 9}, {'source': 'Allyson', 'target': 'Kroger', 'value': 1}, {'source': 'Allyson', 'target': 'Albanese Tropical', 'value': 6}, {'source': 'Allyson', 'target': 'Black Forest', 'value': 7}, {'source': 'Ricky', 'target': 'Haribo', 'value': 6}, {'source': 'Ricky', 'target': 'Sweet Smiles', 'value': 9}, {'source': 'Ricky', 'target': 'Lolli&Pops', 'value': 3}, {'source': 'Ricky', 'target': 'Tooty Fruity', 'value': 2}, {'source': 'Ricky', 'target': "Herbert's Best", 'value': 5}, {'source': 'Ricky', 'target': 'HEB ', 'value': 12}, {'source': 'Ricky', 'target': "Lily's Sweet Fruity", 'value': 7}, {'source': 'Ricky', 'target': 'Albanese', 'value': 10}, {'source': 'Ricky', 'target': 'Organic Tiny', 'value': 8}, {'source': 'Ricky', 'target': 'Kroger', 'value': 11}, {'source': 'Ricky', 'target': 'Albanese Tropical', 'value': 4}, {'source': 'Ricky', 'target': 'Black Forest', 'value': 1}, {'source': 'Luis', 'target': 'Haribo', 'value': 1}, {'source': 'Luis', 'target': 'Sweet Smiles', 'value': 4}, {'source': 'Luis', 'target': 'Lolli&Pops', 'value': 3}, {'source': 'Luis', 'target': 'Tooty Fruity', 'value': 12}, {'source': 'Luis', 'target': "Herbert's Best", 'value': 2}, {'source': 'Luis', 'target': 'HEB ', 'value': 7}, {'source': 'Luis', 'target': "Lily's Sweet Fruity", 'value': 5}, {'source': 'Luis', 'target': 'Albanese', 'value': 6}, {'source': 'Luis', 'target': 'Organic Tiny', 'value': 9}, {'source': 'Luis', 'target': 'Kroger', 'value': 10}, {'source': 'Luis', 'target': 'Albanese Tropical', 'value': 11}, {'source': 'Luis', 'target': 'Black Forest', 'value': 8}]
nodes
[{'name': 'Ben', 'group': 'left'}, {'name': 'Holly', 'group': 'left'}, {'name': 'Andy', 'group': 'left'}, {'name': 'Gretchen', 'group': 'left'}, {'name': 'Matt', 'group': 'left'}, {'name': 'Gary', 'group': 'left'}, {'name': 'Becca', 'group': 'left'}, {'name': 'Ashley', 'group': 'left'}, {'name': 'John', 'group': 'left'}, {'name': 'Gina', 'group': 'left'}, {'name': 'Aaron', 'group': 'left'}, {'name': 'Natalie', 'group': 'left'}, {'name': 'Justin', 'group': 'left'}, {'name': 'Liv', 'group': 'left'}, {'name': 'Dave', 'group': 'left'}, {'name': 'Allyson', 'group': 'left'}, {'name': 'Ricky', 'group': 'left'}, {'name': 'Luis', 'group': 'left'}, {'name': 'HEB ', 'group': 'right'}, {'name': 'Albanese', 'group': 'right'}, {'name': 'Sweet Smiles', 'group': 'right'}, {'name': 'Kroger', 'group': 'right'}, {'name': 'Haribo', 'group': 'right'}, {'name': 'Organic Tiny', 'group': 'right'}, {'name': 'Tooty Fruity', 'group': 'right'}, {'name': 'Albanese Tropical', 'group': 'right'}, {'name': 'Black Forest', 'group': 'right'}, {'name': 'Lolli&Pops', 'group': 'right'}, {'name': "Herbert's Best", 'group': 'right'}, {'name': "Lily's Sweet Fruity", 'group': 'right'}]
SplitChord(links, nodes, margin=180, width=1000, noun="out of 12", verb="as", conjunction="was scored by").show()
import json
data = {"links": links,
"nodes": nodes}
with open("gummy.json", "w") as fp:
json.dump(data, fp)