Engaging plots, made easy.

Easily turn your data into engaging visualizations. Powerful API for coders. Powerful app for everyone.

main.py
notebook.ipynb
main.rs
from plotapi import Chord

Chord(matrix, names).show()

Visualizations Showcase

StamiStudios.com Everyday Ita Bag - Panels and Colours

StamiStudios.com Everyday Ita Bag - Panels and Colours


Preamble

import numpy as np                   # for multi-dimensional containers 
import pandas as pd                  # for DataFrames
import itertools
from plotapi import Chord

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 TidyTuesday Animal Crossing villagers dataset to visualise the relationship between Species and .

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 = 'https://datacrayon.com/datasets/stami_bags_panel_colour.csv'
data = pd.read_csv(data_url)
data.head()
panel colour
0 Heart Pink
1 Circle lilac
2 Sakura Mint
3 circle mint
4 Animal Black
#data['Country.of.Origin'][data['Country.of.Origin'] == 'United States (Hawaii)'] = 'Hawaii'
#data['Country.of.Origin'][data['Country.of.Origin'] == 'Tanzania, United Republic Of'] = 'Tanzania'
#data = data[data.Variety != 'Other']
data = data[data.notna()]
data = data[data['panel'].isin(list(data['panel'].value_counts()[:20].index))]
data = data[data['colour'].isin(list(data['colour'].value_counts()[:11].index))]

capitalise the name, personality, and species of each villager.

data['panel'] = data['panel'].str.capitalize()
data['colour'] = data['colour'].str.capitalize()

It looks good so far, but let's confirm the 13 variables against 1017 samples from the documentation.

data.shape
(3040, 2)
d_colours = list(data.colour.value_counts().index)
d_colours.sort()
d_colours
['Black', 'Blue', 'Green', 'Lilac', 'Mint', 'Navy', 'Pink', 'White', 'Yellow']

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.

species_personality = pd.DataFrame(data[['colour', 'panel']].values).dropna().astype(str)
species_personality
0 1
0 Pink Heart
1 Mint Sakura
2 Black Animal
3 White Circle
4 White Star
... ... ...
3035 Blue Circle
3036 White Circle
3037 White Heart
3038 White Circle
3039 Black Circle

3040 rows × 2 columns

species_personality = species_personality.dropna()

Now for the names of our types.

#left = np.unique(pd.DataFrame(species_personality)[0]).tolist()
left = list(data['colour'].value_counts().index)[::-1]
#left.sort()

pd.DataFrame(left)
0
0 Yellow
1 Green
2 Blue
3 Navy
4 Mint
5 Lilac
6 Pink
7 White
8 Black
#right = np.unique(pd.DataFrame(species_personality)[1]).tolist()
right = list(data['panel'].value_counts().index)
#right.sort()
pd.DataFrame(right)
0
0 Circle
1 Star
2 Crescent
3 Moon
4 Bat wings
5 Sakura
6 Heart
7 Dice20
8 Frog
9 Animal
10 Feline-ears
11 Cat
12 Angel-wings
13 Hive
14 Bottle
15 Paw
16 Petals
17 Pixel
18 Citrus

Which we can now use to create the matrix.

features= left+right
d = pd.DataFrame(0, index=features, columns=features)

Our chord diagram will need two inputs: the co-occurrence matrix, and a list of names to label the segments.

We can build 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.

species_personality = list(itertools.chain.from_iterable((i, i[::-1]) for i in species_personality.values))
for x in species_personality:
    d.at[x[0], x[1]] += 1
d=d/(d.values.sum()/2)*100
d
Yellow Green Blue Navy Mint Lilac Pink White Black Circle ... Animal Feline-ears Cat Angel-wings Hive Bottle Paw Petals Pixel Citrus
Yellow 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.032895 ... 0.000000 0.000000 0.000000 0.000000 0.230263 0.000000 0.032895 0.032895 0.000000 0.855263
Green 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.032895
Blue 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.394737 ... 0.296053 0.197368 0.164474 0.164474 0.000000 0.361842 0.098684 0.000000 0.098684 0.000000
Navy 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.625000 ... 0.131579 0.098684 0.263158 0.000000 0.164474 0.328947 0.131579 0.065789 0.098684 0.098684
Mint 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.361842 ... 0.098684 0.000000 0.131579 0.032895 0.065789 0.098684 0.263158 0.065789 0.197368 0.263158
Lilac 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.723684 ... 0.493421 0.296053 0.493421 0.032895 0.098684 0.460526 0.296053 0.526316 0.263158 0.065789
Pink 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.986842 ... 0.427632 0.328947 0.361842 0.263158 0.263158 0.032895 0.328947 0.789474 0.394737 0.164474
White 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.927632 ... 1.348684 0.493421 0.493421 2.861842 0.625000 0.361842 0.263158 0.657895 0.197368 0.361842
Black 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 7.796053 ... 1.940789 3.289474 2.138158 0.427632 1.743421 1.315789 0.953947 0.098684 0.953947 0.164474
Circle 0.032895 0.000000 0.394737 0.625000 0.361842 0.723684 0.986842 2.927632 7.796053 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Star 0.098684 0.000000 0.625000 0.427632 0.493421 0.723684 1.118421 1.513158 3.684211 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Crescent 0.098684 0.000000 0.328947 0.657895 0.197368 0.789474 1.743421 0.855263 3.256579 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Moon 0.164474 0.000000 0.690789 0.855263 0.361842 0.921053 0.723684 0.953947 3.059211 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Bat wings 0.000000 0.000000 0.098684 0.230263 0.032895 0.394737 0.065789 0.197368 6.644737 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Sakura 0.000000 0.000000 0.230263 0.065789 0.197368 0.394737 3.026316 0.953947 1.414474 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Heart 0.000000 0.000000 0.164474 0.098684 0.164474 0.592105 1.940789 0.888158 1.743421 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Dice20 0.000000 0.000000 0.164474 0.328947 0.230263 0.493421 0.394737 0.427632 2.993421 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Frog 0.000000 2.565789 0.065789 0.000000 1.907895 0.098684 0.328947 0.032895 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Animal 0.000000 0.000000 0.296053 0.131579 0.098684 0.493421 0.427632 1.348684 1.940789 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Feline-ears 0.000000 0.000000 0.197368 0.098684 0.000000 0.296053 0.328947 0.493421 3.289474 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Cat 0.000000 0.000000 0.164474 0.263158 0.131579 0.493421 0.361842 0.493421 2.138158 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Angel-wings 0.000000 0.000000 0.164474 0.000000 0.032895 0.032895 0.263158 2.861842 0.427632 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Hive 0.230263 0.000000 0.000000 0.164474 0.065789 0.098684 0.263158 0.625000 1.743421 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Bottle 0.000000 0.000000 0.361842 0.328947 0.098684 0.460526 0.032895 0.361842 1.315789 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Paw 0.032895 0.000000 0.098684 0.131579 0.263158 0.296053 0.328947 0.263158 0.953947 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Petals 0.032895 0.000000 0.000000 0.065789 0.065789 0.526316 0.789474 0.657895 0.098684 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Pixel 0.000000 0.000000 0.098684 0.098684 0.197368 0.263158 0.394737 0.197368 0.953947 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
Citrus 0.855263 0.032895 0.000000 0.098684 0.263158 0.065789 0.164474 0.361842 0.164474 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

28 rows × 28 columns

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 =["#ffe75f", "#85e063", "#aed6f8", "#1e3c6f", "#affec6", "#d3b0e7", "#fedbe8", "#f5f4e9", "#222222", "#f7a296", "#f48fb1", "#ce93d8", "#a9a3db", "#89cffa", "#80deea", "#80cbc4", "#a5d6a7", "#e6ee9c", "#fff59d", "#ffe082", "#ffcc80", "#f7a296", "#f06292", "#a76fcb", "#7986cb", "#64b5f6", "#4ecaec", "#4db6ac"]
names = left + right

Finally, we can put it all together.

Chord(
    d.values.round(2).tolist(),
    names,
    colors=colors,
    margin=70,
    noun="percent",
    details_separator="",
    bipartite=True,
    bipartite_idx=len(left),
    bipartite_size=0.5,
    width=850,
).show()


import json

data = {"matrix": d.values.round(2).tolist(),
        "names": names,
        "colors": colors,
        "bipartite_idx": len(left)}

with open("stamistudios.json", "w") as fp:
    json.dump(data, fp)
PlotAPI - Chord Diagram

Previous
Showcase