Visualizations Showcase
Preamble
Preamble
import numpy as np # for multi-dimensional containers
import pandas as pd # for DataFrames
import itertools
from plotapi import Chord
username = "shahin@plotapi.com"
password = "PLOTAPI-B-7ef36302-6439-40ec-8218-9d1e6d9fb0aa"
Chord.set_license(username, password)
Introduction
In previous sections, we visualised co-occurrences of Pokémon type. Whilst it was interesting to look at, the dataset only contained Pokémon from the first six geerations. In this section, we're going to use the Pokemon with stats Generation 8 dataset to visualise the co-occurrence of Pokémon types from generations one to eight.
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_url = 'pokemon.csv'
data = pd.read_csv(data_url)
data["url"] = "https://datacrayon.com/datasets/pokemon_img/"+data["image_name"]
#data['display_name'] = ""
data.head()
#data['name'] = data['name'].str.slice(0,10)
Unnamed: 0 | pokedex_id | generation | form | form_generation | display_generation | name | display_name | color | type_1 | type_2 | evolutions | image_url | image_name | url | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 1 | Bulbasaur | 1 | 1 | Bulbasaur | Bulbasaur | (126, 173, 145) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 001.png | https://datacrayon.com/datasets/pokemon_img/00... |
1 | 1 | 2 | 1 | Ivysaur | 1 | 1 | Ivysaur | Ivysaur | (107, 156, 154) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 002.png | https://datacrayon.com/datasets/pokemon_img/00... |
2 | 2 | 3 | 1 | Venusaur | 1 | 1 | Venusaur | Venusaur | (93, 137, 127) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003.png | https://datacrayon.com/datasets/pokemon_img/00... |
3 | 3 | 3 | 1 | Mega Venusaur | 6 | 1→6 | Venusaur | Mega Venusaur | (98, 149, 137) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-mega-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
4 | 4 | 3 | 1 | Gigantamax Venusaur | 8 | 1→8 | Venusaur | Gigantamax Venusaur | (97, 73, 71) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-gigantamax-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
#banlist = [
# " Form",
# " Forme",
# " Style",
# " Pattern",
# " Reversion",
# " Cloak",
# " Mode"
#]
#
#for idx, pok in data.iterrows():
# if(pok['name'] in pok['form']):
# data.at[idx, 'display_name'] = pok['form']
# else:
# data.at[idx, 'display_name'] = pok['form'] + " " + pok['name']
#
#
# for word in banlist:
# data.at[idx, 'display_name'] = data.at[idx, 'display_name'].replace(word,"")
#
It looks good so far, but let's confirm the 13 variables against 1017 samples from the documentation.
data.loc[98]
Unnamed: 0 98 pokedex_id 71 generation 1 form Victreebel form_generation 1 display_generation 1 name Victreebel display_name Victreebel color (175, 205, 133) type_1 Grass type_2 Poison evolutions [69, 70, 71] image_url https://assets.pokemon.com/assets/cms2/img/pok... image_name 071.png url https://datacrayon.com/datasets/pokemon_img/07... Name: 98, dtype: object
data.shape
data.columns
Index(['Unnamed: 0', 'pokedex_id', 'generation', 'form', 'form_generation', 'display_generation', 'name', 'display_name', 'color', 'type_1', 'type_2', 'evolutions', 'image_url', 'image_name', 'url'], dtype='object')
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
.
pd.DataFrame(data.columns.values.tolist())
0 | |
---|---|
0 | Unnamed: 0 |
1 | pokedex_id |
2 | generation |
3 | form |
4 | form_generation |
5 | display_generation |
6 | name |
7 | display_name |
8 | color |
9 | type_1 |
10 | type_2 |
11 | evolutions |
12 | image_url |
13 | image_name |
14 | url |
So let's select just these two columns and work with a list containing only them as we move forward.
types = pd.DataFrame(data[['type_1', 'type_2']].values)
types
0 | 1 | |
---|---|---|
0 | Grass | Poison |
1 | Grass | Poison |
2 | Grass | Poison |
3 | Grass | Poison |
4 | Grass | Poison |
... | ... | ... |
1226 | Dark | Fire |
1227 | Dragon | Dark |
1228 | Fairy | Fighting |
1229 | Fighting | Dragon |
1230 | Electric | Dragon |
1231 rows × 2 columns
Without further investigation, we can see that we have at least a few NaN
values in the table above. We are only interested in co-occurrence of types, so we can remove all samples which contain a NaN
value.
#types = types.dropna()
We can also see an instance where the type Fighting
at index \n
. We'll strip all these out before continuing.
types = types.replace('\n','', regex=True)
types
0 | 1 | |
---|---|---|
0 | Grass | Poison |
1 | Grass | Poison |
2 | Grass | Poison |
3 | Grass | Poison |
4 | Grass | Poison |
... | ... | ... |
1226 | Dark | Fire |
1227 | Dragon | Dark |
1228 | Fairy | Fighting |
1229 | Fighting | Dragon |
1230 | Electric | Dragon |
1231 rows × 2 columns
Our chord diagram will need two inputs: the co-occurrence matrix, and a list of names to label the segments.
First we'll populate our list of type names by looking for the unique ones.
names =np.unique(pd.concat([types[col] for col in types]).dropna()).tolist()
pd.DataFrame(names)
0 | |
---|---|
0 | Bug |
1 | Dark |
2 | Dragon |
3 | Electric |
4 | Fairy |
5 | Fighting |
6 | Fire |
7 | Flying |
8 | Ghost |
9 | Grass |
10 | Ground |
11 | Ice |
12 | Normal |
13 | Poison |
14 | Psychic |
15 | Rock |
16 | Steel |
17 | Water |
Now we can create our empty co-occurrence matrix using these type names for the row and column indeces.
We can populate a co-occurrence matrix with the following approach. We'll start by creating a list with every type pairing in its original and reversed form.
types
0 | 1 | |
---|---|---|
0 | Grass | Poison |
1 | Grass | Poison |
2 | Grass | Poison |
3 | Grass | Poison |
4 | Grass | Poison |
... | ... | ... |
1226 | Dark | Fire |
1227 | Dragon | Dark |
1228 | Fairy | Fighting |
1229 | Fighting | Dragon |
1230 | Electric | Dragon |
1231 rows × 2 columns
Which we can now use to create the matrix.
##for t in types:
# matrix.at[t[0], t[1]] += 1
#matrix = matrix.values.tolist()
We can list the DataFrame
for better presentation.
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.
colors = ["#A6B91A", "#705746", "#6F35FC", "#F7D02C", "#D685AD",
"#C22E28", "#EE8130", "#A98FF3", "#735797", "#7AC74C",
"#E2BF65", "#96D9D6", "#A8A77A", "#A33EA1", "#F95587",
"#B6A136", "#B7B7CE", "#6390F0"]
names
['Bug', 'Dark', 'Dragon', 'Electric', 'Fairy', 'Fighting', 'Fire', 'Flying', 'Ghost', 'Grass', 'Ground', 'Ice', 'Normal', 'Poison', 'Psychic', 'Rock', 'Steel', 'Water']
Finally, we can put it all together.
Chord Diagram with Names
It would be nice to show a list of Pokémon names and images when hovering over co-occurring Pokémon types. To do this, we can make use of the optional details
parameter.
Let's clean up our dataset by removing all instances of \n
.
data = data.replace('\n','', regex=True)
Let's also add a column to our dataset to store URLs that point to the images.
Next, we'll create an empty multi-dimensional arrays with the same shape as our matrix
for our details and thumbnail images.
data
Unnamed: 0 | pokedex_id | generation | form | form_generation | display_generation | name | display_name | color | type_1 | type_2 | evolutions | image_url | image_name | url | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 1 | Bulbasaur | 1 | 1 | Bulbasaur | Bulbasaur | (126, 173, 145) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 001.png | https://datacrayon.com/datasets/pokemon_img/00... |
1 | 1 | 2 | 1 | Ivysaur | 1 | 1 | Ivysaur | Ivysaur | (107, 156, 154) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 002.png | https://datacrayon.com/datasets/pokemon_img/00... |
2 | 2 | 3 | 1 | Venusaur | 1 | 1 | Venusaur | Venusaur | (93, 137, 127) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003.png | https://datacrayon.com/datasets/pokemon_img/00... |
3 | 3 | 3 | 1 | Mega Venusaur | 6 | 1→6 | Venusaur | Mega Venusaur | (98, 149, 137) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-mega-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
4 | 4 | 3 | 1 | Gigantamax Venusaur | 8 | 1→8 | Venusaur | Gigantamax Venusaur | (97, 73, 71) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-gigantamax-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1226 | 1226 | 1004 | 9 | Chi-Yu | 9 | 9 | Chi-Yu | Chi-Yu | (168, 53, 36) | Dark | Fire | [1004] | https://assets.pokemon.com/assets/cms2/img/pok... | 1004.png | https://datacrayon.com/datasets/pokemon_img/10... |
1227 | 1227 | 1005 | 9 | Roaring Moon | 9 | 9 | Roaring Moon | Roaring Moon | (184, 40, 68) | Dragon | Dark | [1005] | https://assets.pokemon.com/assets/cms2/img/pok... | 1005.png | https://datacrayon.com/datasets/pokemon_img/10... |
1228 | 1228 | 1006 | 9 | Iron Valiant | 9 | 9 | Iron Valiant | Iron Valiant | (55, 101, 71) | Fairy | Fighting | [1006] | https://assets.pokemon.com/assets/cms2/img/pok... | 1006.png | https://datacrayon.com/datasets/pokemon_img/10... |
1229 | 1229 | 1007 | 9 | Koraidon | 9 | 9 | Koraidon | Koraidon | (194, 86, 84) | Fighting | Dragon | [1007] | https://assets.pokemon.com/assets/cms2/img/pok... | 1007.png | https://datacrayon.com/datasets/pokemon_img/10... |
1230 | 1230 | 1008 | 9 | Miraidon | 9 | 9 | Miraidon | Miraidon | (76, 69, 135) | Electric | Dragon | [1008] | https://assets.pokemon.com/assets/cms2/img/pok... | 1008.png | https://datacrayon.com/datasets/pokemon_img/10... |
1231 rows × 15 columns
data
Unnamed: 0 | pokedex_id | generation | form | form_generation | display_generation | name | display_name | color | type_1 | type_2 | evolutions | image_url | image_name | url | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 1 | Bulbasaur | 1 | 1 | Bulbasaur | Bulbasaur | (126, 173, 145) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 001.png | https://datacrayon.com/datasets/pokemon_img/00... |
1 | 1 | 2 | 1 | Ivysaur | 1 | 1 | Ivysaur | Ivysaur | (107, 156, 154) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 002.png | https://datacrayon.com/datasets/pokemon_img/00... |
2 | 2 | 3 | 1 | Venusaur | 1 | 1 | Venusaur | Venusaur | (93, 137, 127) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003.png | https://datacrayon.com/datasets/pokemon_img/00... |
3 | 3 | 3 | 1 | Mega Venusaur | 6 | 1→6 | Venusaur | Mega Venusaur | (98, 149, 137) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-mega-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
4 | 4 | 3 | 1 | Gigantamax Venusaur | 8 | 1→8 | Venusaur | Gigantamax Venusaur | (97, 73, 71) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-gigantamax-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1226 | 1226 | 1004 | 9 | Chi-Yu | 9 | 9 | Chi-Yu | Chi-Yu | (168, 53, 36) | Dark | Fire | [1004] | https://assets.pokemon.com/assets/cms2/img/pok... | 1004.png | https://datacrayon.com/datasets/pokemon_img/10... |
1227 | 1227 | 1005 | 9 | Roaring Moon | 9 | 9 | Roaring Moon | Roaring Moon | (184, 40, 68) | Dragon | Dark | [1005] | https://assets.pokemon.com/assets/cms2/img/pok... | 1005.png | https://datacrayon.com/datasets/pokemon_img/10... |
1228 | 1228 | 1006 | 9 | Iron Valiant | 9 | 9 | Iron Valiant | Iron Valiant | (55, 101, 71) | Fairy | Fighting | [1006] | https://assets.pokemon.com/assets/cms2/img/pok... | 1006.png | https://datacrayon.com/datasets/pokemon_img/10... |
1229 | 1229 | 1007 | 9 | Koraidon | 9 | 9 | Koraidon | Koraidon | (194, 86, 84) | Fighting | Dragon | [1007] | https://assets.pokemon.com/assets/cms2/img/pok... | 1007.png | https://datacrayon.com/datasets/pokemon_img/10... |
1230 | 1230 | 1008 | 9 | Miraidon | 9 | 9 | Miraidon | Miraidon | (76, 69, 135) | Electric | Dragon | [1008] | https://assets.pokemon.com/assets/cms2/img/pok... | 1008.png | https://datacrayon.com/datasets/pokemon_img/10... |
1231 rows × 15 columns
data
Unnamed: 0 | pokedex_id | generation | form | form_generation | display_generation | name | display_name | color | type_1 | type_2 | evolutions | image_url | image_name | url | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 1 | Bulbasaur | 1 | 1 | Bulbasaur | Bulbasaur | (126, 173, 145) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 001.png | https://datacrayon.com/datasets/pokemon_img/00... |
1 | 1 | 2 | 1 | Ivysaur | 1 | 1 | Ivysaur | Ivysaur | (107, 156, 154) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 002.png | https://datacrayon.com/datasets/pokemon_img/00... |
2 | 2 | 3 | 1 | Venusaur | 1 | 1 | Venusaur | Venusaur | (93, 137, 127) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003.png | https://datacrayon.com/datasets/pokemon_img/00... |
3 | 3 | 3 | 1 | Mega Venusaur | 6 | 1→6 | Venusaur | Mega Venusaur | (98, 149, 137) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-mega-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
4 | 4 | 3 | 1 | Gigantamax Venusaur | 8 | 1→8 | Venusaur | Gigantamax Venusaur | (97, 73, 71) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-gigantamax-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1226 | 1226 | 1004 | 9 | Chi-Yu | 9 | 9 | Chi-Yu | Chi-Yu | (168, 53, 36) | Dark | Fire | [1004] | https://assets.pokemon.com/assets/cms2/img/pok... | 1004.png | https://datacrayon.com/datasets/pokemon_img/10... |
1227 | 1227 | 1005 | 9 | Roaring Moon | 9 | 9 | Roaring Moon | Roaring Moon | (184, 40, 68) | Dragon | Dark | [1005] | https://assets.pokemon.com/assets/cms2/img/pok... | 1005.png | https://datacrayon.com/datasets/pokemon_img/10... |
1228 | 1228 | 1006 | 9 | Iron Valiant | 9 | 9 | Iron Valiant | Iron Valiant | (55, 101, 71) | Fairy | Fighting | [1006] | https://assets.pokemon.com/assets/cms2/img/pok... | 1006.png | https://datacrayon.com/datasets/pokemon_img/10... |
1229 | 1229 | 1007 | 9 | Koraidon | 9 | 9 | Koraidon | Koraidon | (194, 86, 84) | Fighting | Dragon | [1007] | https://assets.pokemon.com/assets/cms2/img/pok... | 1007.png | https://datacrayon.com/datasets/pokemon_img/10... |
1230 | 1230 | 1008 | 9 | Miraidon | 9 | 9 | Miraidon | Miraidon | (76, 69, 135) | Electric | Dragon | [1008] | https://assets.pokemon.com/assets/cms2/img/pok... | 1008.png | https://datacrayon.com/datasets/pokemon_img/10... |
1231 rows × 15 columns
Now we can populate the details
array with lists of Pokémon names in the correct positions.
data
Unnamed: 0 | pokedex_id | generation | form | form_generation | display_generation | name | display_name | color | type_1 | type_2 | evolutions | image_url | image_name | url | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 1 | Bulbasaur | 1 | 1 | Bulbasaur | Bulbasaur | (126, 173, 145) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 001.png | https://datacrayon.com/datasets/pokemon_img/00... |
1 | 1 | 2 | 1 | Ivysaur | 1 | 1 | Ivysaur | Ivysaur | (107, 156, 154) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 002.png | https://datacrayon.com/datasets/pokemon_img/00... |
2 | 2 | 3 | 1 | Venusaur | 1 | 1 | Venusaur | Venusaur | (93, 137, 127) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003.png | https://datacrayon.com/datasets/pokemon_img/00... |
3 | 3 | 3 | 1 | Mega Venusaur | 6 | 1→6 | Venusaur | Mega Venusaur | (98, 149, 137) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-mega-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
4 | 4 | 3 | 1 | Gigantamax Venusaur | 8 | 1→8 | Venusaur | Gigantamax Venusaur | (97, 73, 71) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-gigantamax-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1226 | 1226 | 1004 | 9 | Chi-Yu | 9 | 9 | Chi-Yu | Chi-Yu | (168, 53, 36) | Dark | Fire | [1004] | https://assets.pokemon.com/assets/cms2/img/pok... | 1004.png | https://datacrayon.com/datasets/pokemon_img/10... |
1227 | 1227 | 1005 | 9 | Roaring Moon | 9 | 9 | Roaring Moon | Roaring Moon | (184, 40, 68) | Dragon | Dark | [1005] | https://assets.pokemon.com/assets/cms2/img/pok... | 1005.png | https://datacrayon.com/datasets/pokemon_img/10... |
1228 | 1228 | 1006 | 9 | Iron Valiant | 9 | 9 | Iron Valiant | Iron Valiant | (55, 101, 71) | Fairy | Fighting | [1006] | https://assets.pokemon.com/assets/cms2/img/pok... | 1006.png | https://datacrayon.com/datasets/pokemon_img/10... |
1229 | 1229 | 1007 | 9 | Koraidon | 9 | 9 | Koraidon | Koraidon | (194, 86, 84) | Fighting | Dragon | [1007] | https://assets.pokemon.com/assets/cms2/img/pok... | 1007.png | https://datacrayon.com/datasets/pokemon_img/10... |
1230 | 1230 | 1008 | 9 | Miraidon | 9 | 9 | Miraidon | Miraidon | (76, 69, 135) | Electric | Dragon | [1008] | https://assets.pokemon.com/assets/cms2/img/pok... | 1008.png | https://datacrayon.com/datasets/pokemon_img/10... |
1231 rows × 15 columns
data.loc[98]
Unnamed: 0 98 pokedex_id 71 generation 1 form Victreebel form_generation 1 display_generation 1 name Victreebel display_name Victreebel color (175, 205, 133) type_1 Grass type_2 Poison evolutions [69, 70, 71] image_url https://assets.pokemon.com/assets/cms2/img/pok... image_name 071.png url https://datacrayon.com/datasets/pokemon_img/07... Name: 98, dtype: object
matrix = pd.DataFrame(0, index=names, columns=names)
details = pd.DataFrame([[[] for i in range(len(names))] for i in range(len(names))], index=names, columns=names)
details_thumbs = pd.DataFrame([[[] for i in range(len(names))] for i in range(len(names))], index=names, columns=names)
details
names_nested = names.copy()
print
for count_x, item_x in enumerate(names):
for count_y, item_y in enumerate(names_nested):
details_urls = data[
(data['type_1'].isin([item_x, item_y])) &
(data['type_2'].isin([item_y, item_x]))]['url'].to_list()
details_names = data[
(data['type_1'].isin([item_x, item_y])) &
(data['type_2'].isin([item_y, item_x]))]['display_name'].to_list()
urls_names = np.column_stack((details_urls, details_names))
if(urls_names.size > 0):
details[item_y][item_x] = details_names
details_thumbs[item_y][item_x] = details_urls
#print(item_x + ":" + item_y)
#print(details_names)
matrix[item_y][item_x] = len(details_names)
#else:
#details[item_x][item_y] = []
#details_thumbs[item_x][item_y] = []
# names_nested.remove(item_x)
for count_x, item_x in enumerate(names):
details_urls = data[
(data['type_1'].isin([item_x])) &
(data['type_2'].isna())]['url'].to_list()
details_names = data[
(data['type_1'].isin([item_x])) &
(data['type_2'].isna())]['display_name'].to_list()
urls_names = np.column_stack((details_urls, details_names))
if(urls_names.size > 0):
details[item_x][item_x] = details_names
details_thumbs[item_x][item_x] = details_urls
matrix[item_x][item_x] = len(details_urls)
#else:
# details[item_x][item_x] = []
# details_thumbs[item_x][item_x] = []
details=pd.DataFrame(details).values.tolist()
details_thumbs=pd.DataFrame(details_thumbs).values.tolist()
names_nested
['Bug', 'Dark', 'Dragon', 'Electric', 'Fairy', 'Fighting', 'Fire', 'Flying', 'Ghost', 'Grass', 'Ground', 'Ice', 'Normal', 'Poison', 'Psychic', 'Rock', 'Steel', 'Water']
matrix.sum()
Bug 110 Dark 91 Dragon 89 Electric 87 Fairy 76 Fighting 94 Fire 97 Flying 143 Ghost 80 Grass 142 Ground 91 Ice 63 Normal 162 Poison 95 Psychic 131 Rock 87 Steel 87 Water 183 dtype: int64
print(names)
['Bug', 'Dark', 'Dragon', 'Electric', 'Fairy', 'Fighting', 'Fire', 'Flying', 'Ghost', 'Grass', 'Ground', 'Ice', 'Normal', 'Poison', 'Psychic', 'Rock', 'Steel', 'Water']
type_colors = dict(zip(names, colors))
type_colors
{'Bug': '#A6B91A', 'Dark': '#705746', 'Dragon': '#6F35FC', 'Electric': '#F7D02C', 'Fairy': '#D685AD', 'Fighting': '#C22E28', 'Fire': '#EE8130', 'Flying': '#A98FF3', 'Ghost': '#735797', 'Grass': '#7AC74C', 'Ground': '#E2BF65', 'Ice': '#96D9D6', 'Normal': '#A8A77A', 'Poison': '#A33EA1', 'Psychic': '#F95587', 'Rock': '#B6A136', 'Steel': '#B7B7CE', 'Water': '#6390F0'}
for index, row in data.iterrows():
dex = f"{row['pokedex_id']:03d}"
url = f"https://www.pokemon.com/uk/pokedex/{dex}"
data.at[index,'dex_site'] = f'<a href="{url}">{row["display_name"]}</a>'
data['dex_site']
data_table = data[['type_1', "type_2", "pokedex_id","display_generation","dex_site"]]
data_table["URL"] = '<img src="'+data['url'] +'">'
data_table = data_table.fillna('')
data_table["display_generation"] = '<span class="gen">'+data_table["display_generation"]+'</span>'
data_table["pokedex_id"] = '<span class="'+data_table["type_1"]+'">'+data_table["type_1"]+'</span> <span class="'+data_table["type_2"]+'">'+data_table["type_2"]+'</span>'
data_table.columns = ['Type 1', 'Type 2', 'Type', 'Gen', 'Name', '']
data_table
/var/folders/2j/4xqwdh2x1d11bcq2xhgd65r40000gn/T/ipykernel_7136/966321649.py:10: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy data_table["URL"] = ''
Type 1 | Type 2 | Type | Gen | Name | ||
---|---|---|---|---|---|---|
0 | Grass | Poison | <span class="Grass">Grass</span> <span class="... | <span class="gen">1</span> | <a href="https://www.pokemon.com/uk/pokedex/00... | <img src="https://datacrayon.com/datasets/poke... |
1 | Grass | Poison | <span class="Grass">Grass</span> <span class="... | <span class="gen">1</span> | <a href="https://www.pokemon.com/uk/pokedex/00... | <img src="https://datacrayon.com/datasets/poke... |
2 | Grass | Poison | <span class="Grass">Grass</span> <span class="... | <span class="gen">1</span> | <a href="https://www.pokemon.com/uk/pokedex/00... | <img src="https://datacrayon.com/datasets/poke... |
3 | Grass | Poison | <span class="Grass">Grass</span> <span class="... | <span class="gen">1→6</span> | <a href="https://www.pokemon.com/uk/pokedex/00... | <img src="https://datacrayon.com/datasets/poke... |
4 | Grass | Poison | <span class="Grass">Grass</span> <span class="... | <span class="gen">1→8</span> | <a href="https://www.pokemon.com/uk/pokedex/00... | <img src="https://datacrayon.com/datasets/poke... |
... | ... | ... | ... | ... | ... | ... |
1226 | Dark | Fire | <span class="Dark">Dark</span> <span class="Fi... | <span class="gen">9</span> | <a href="https://www.pokemon.com/uk/pokedex/10... | <img src="https://datacrayon.com/datasets/poke... |
1227 | Dragon | Dark | <span class="Dragon">Dragon</span> <span class... | <span class="gen">9</span> | <a href="https://www.pokemon.com/uk/pokedex/10... | <img src="https://datacrayon.com/datasets/poke... |
1228 | Fairy | Fighting | <span class="Fairy">Fairy</span> <span class="... | <span class="gen">9</span> | <a href="https://www.pokemon.com/uk/pokedex/10... | <img src="https://datacrayon.com/datasets/poke... |
1229 | Fighting | Dragon | <span class="Fighting">Fighting</span> <span c... | <span class="gen">9</span> | <a href="https://www.pokemon.com/uk/pokedex/10... | <img src="https://datacrayon.com/datasets/poke... |
1230 | Electric | Dragon | <span class="Electric">Electric</span> <span c... | <span class="gen">9</span> | <a href="https://www.pokemon.com/uk/pokedex/10... | <img src="https://datacrayon.com/datasets/poke... |
1231 rows × 6 columns
data
Unnamed: 0 | pokedex_id | generation | form | form_generation | display_generation | name | display_name | color | type_1 | type_2 | evolutions | image_url | image_name | url | dex_site | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 1 | Bulbasaur | 1 | 1 | Bulbasaur | Bulbasaur | (126, 173, 145) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 001.png | https://datacrayon.com/datasets/pokemon_img/00... | <a href="https://www.pokemon.com/uk/pokedex/00... |
1 | 1 | 2 | 1 | Ivysaur | 1 | 1 | Ivysaur | Ivysaur | (107, 156, 154) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 002.png | https://datacrayon.com/datasets/pokemon_img/00... | <a href="https://www.pokemon.com/uk/pokedex/00... |
2 | 2 | 3 | 1 | Venusaur | 1 | 1 | Venusaur | Venusaur | (93, 137, 127) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003.png | https://datacrayon.com/datasets/pokemon_img/00... | <a href="https://www.pokemon.com/uk/pokedex/00... |
3 | 3 | 3 | 1 | Mega Venusaur | 6 | 1→6 | Venusaur | Mega Venusaur | (98, 149, 137) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-mega-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... | <a href="https://www.pokemon.com/uk/pokedex/00... |
4 | 4 | 3 | 1 | Gigantamax Venusaur | 8 | 1→8 | Venusaur | Gigantamax Venusaur | (97, 73, 71) | Grass | Poison | [1, 2, 3] | https://assets.pokemon.com/assets/cms2/img/pok... | 003-gigantamax-venusaur.png | https://datacrayon.com/datasets/pokemon_img/00... | <a href="https://www.pokemon.com/uk/pokedex/00... |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1226 | 1226 | 1004 | 9 | Chi-Yu | 9 | 9 | Chi-Yu | Chi-Yu | (168, 53, 36) | Dark | Fire | [1004] | https://assets.pokemon.com/assets/cms2/img/pok... | 1004.png | https://datacrayon.com/datasets/pokemon_img/10... | <a href="https://www.pokemon.com/uk/pokedex/10... |
1227 | 1227 | 1005 | 9 | Roaring Moon | 9 | 9 | Roaring Moon | Roaring Moon | (184, 40, 68) | Dragon | Dark | [1005] | https://assets.pokemon.com/assets/cms2/img/pok... | 1005.png | https://datacrayon.com/datasets/pokemon_img/10... | <a href="https://www.pokemon.com/uk/pokedex/10... |
1228 | 1228 | 1006 | 9 | Iron Valiant | 9 | 9 | Iron Valiant | Iron Valiant | (55, 101, 71) | Fairy | Fighting | [1006] | https://assets.pokemon.com/assets/cms2/img/pok... | 1006.png | https://datacrayon.com/datasets/pokemon_img/10... | <a href="https://www.pokemon.com/uk/pokedex/10... |
1229 | 1229 | 1007 | 9 | Koraidon | 9 | 9 | Koraidon | Koraidon | (194, 86, 84) | Fighting | Dragon | [1007] | https://assets.pokemon.com/assets/cms2/img/pok... | 1007.png | https://datacrayon.com/datasets/pokemon_img/10... | <a href="https://www.pokemon.com/uk/pokedex/10... |
1230 | 1230 | 1008 | 9 | Miraidon | 9 | 9 | Miraidon | Miraidon | (76, 69, 135) | Electric | Dragon | [1008] | https://assets.pokemon.com/assets/cms2/img/pok... | 1008.png | https://datacrayon.com/datasets/pokemon_img/10... | <a href="https://www.pokemon.com/uk/pokedex/10... |
1231 rows × 16 columns
print(data_table)
Type 1 Type 2 Type \ 0 Grass Poison Grass Grass Grass Grass Grass Dark Dragon Fairy Fighting Electric 1 1 1 2 1 3 1→6 4 1→8 ... ... 1226 9 1227 9 1228 9 1229 9 1230 9 Name \ 0
Finally, we can put it all together but this time with the details
matrix passed in.
matrix = matrix.values.tolist()
details_thumbs = details_thumbs
data_table = data_table.to_csv(index=False)
import json
data = {"matrix": matrix,
"details_thumbs": details_thumbs,
"data_table": data_table}
with open("pokemon_types.json", "w") as fp:
json.dump(data, fp)
with open("pokemon_types.json", "r") as fp:
b = json.load(fp)
b['matrix']
[[25, 1, 0, 4, 2, 5, 5, 22, 1, 6, 2, 2, 0, 13, 4, 6, 7, 5], [1, 16, 5, 2, 4, 5, 5, 8, 3, 7, 4, 3, 5, 7, 3, 2, 3, 8], [0, 5, 13, 4, 1, 3, 3, 8, 5, 7, 9, 6, 2, 3, 5, 2, 6, 7], [4, 2, 4, 37, 2, 3, 1, 8, 1, 3, 2, 2, 2, 4, 1, 4, 4, 3], [2, 4, 1, 2, 22, 1, 0, 4, 2, 5, 0, 1, 5, 1, 11, 3, 8, 4], [5, 5, 3, 3, 1, 31, 8, 3, 2, 5, 1, 1, 4, 4, 6, 1, 4, 7], [5, 5, 3, 1, 0, 8, 37, 8, 8, 1, 4, 0, 3, 3, 3, 6, 1, 1], [22, 8, 8, 8, 4, 3, 8, 4, 3, 7, 4, 2, 32, 3, 9, 6, 4, 8], [1, 3, 5, 1, 2, 2, 8, 3, 18, 8, 6, 1, 2, 5, 4, 0, 5, 6], [6, 7, 7, 3, 5, 5, 1, 7, 8, 48, 3, 3, 11, 16, 4, 2, 3, 3], [2, 4, 9, 2, 0, 1, 4, 4, 6, 3, 18, 3, 2, 4, 2, 9, 7, 11], [2, 3, 6, 2, 1, 1, 0, 2, 1, 3, 3, 20, 0, 0, 5, 3, 2, 9], [0, 5, 2, 2, 5, 4, 3, 32, 2, 11, 2, 0, 84, 2, 7, 0, 0, 1], [13, 7, 3, 4, 1, 4, 3, 3, 5, 16, 4, 0, 2, 17, 2, 3, 2, 6], [4, 3, 5, 1, 11, 6, 3, 9, 4, 4, 2, 5, 7, 2, 47, 2, 9, 7], [6, 2, 2, 4, 3, 1, 6, 6, 0, 2, 9, 3, 0, 3, 2, 19, 7, 12], [7, 3, 6, 4, 8, 4, 1, 4, 5, 3, 7, 2, 0, 2, 9, 7, 14, 1], [5, 8, 7, 3, 4, 7, 1, 8, 6, 3, 11, 9, 1, 6, 7, 12, 1, 84]]
Chord(
matrix,
names,
colors="monsters",
details_thumbs=details_thumbs,
margin=30,
noun="Pokemon!",
thumbs_width=50,
curved_labels=True,
thumbs_margin=1,
popup_width=600,
thumbs_font_size=10,
credit=True,
arc_numbers=True,
reverse_gradients=False,
data_table_column_width=80,
data_table=data_table,
animated_intro=True,
data_table_show_indices=False
).show()
Chord(
matrix.values.tolist(),
names,
colors="viridis",
details=details,
details_thumbs=details_thumbs,
margin=80,
noun="Pokédsssdasmdsadson",
thumbs_width=50,
thumbs_margin=1,
popup_width=601,
thumbs_font_size=10,
credit=True,
arc_numbers=True,
reverse_gradients=False,
data_table=data_table.to_csv( index=False)
).show()
Chord(
matrix.values.tolist(),
names,
colors="viridis",
details=details,
details_thumbs=details_thumbs,
margin=80,
noun="Posdsxxsdsfsskémon",
thumbs_width=50,
thumbs_margin=1,
popup_width=600,
thumbs_font_size=10,
credit=True,
arc_numbers=True,
reverse_gradients=False,
).show_png()
Conclusion
In this section, we demonstrated how to conduct some data wrangling on a downloaded dataset to prepare it for a chord diagram. Our chord diagram is interactive, so you can use your mouse or touchscreen to investigate the co-occurrences!
matrix.values.tolist()
matrix['Bug']