GraphGists

Introduction

This article explores the relationships between Pokemon and their evolution chains, along with different Pokemon types and their advantages and disadvantages against other types using Neo4J.

:Most of the information is more relevant to the Gamefreak series but there’s also some experimental PokemonGO analysis at the end of the piece. It’s also Generation I only for now.
r918mXE
Figure 1. This is a simplification of what an evolution chain will look like.

Setup: Creating Pokemon, Types and Relationships.

The node and relationship data set is built using data available at https://pokeapi.co and the resulting query.

Starting with the example in Figure 1 above, this query will show the basic evolution chain from Charmander through to Charizard.

MATCH(n:Pokemon)-[r:evolves_to]-()
WHERE n.name IN ['charmander', 'charmeleon', 'charizard']
RETURN r, n

So far the result is a very simple graph. The below query will illustrate when there are multiple evolution paths. Eevee is one such Pokemon in the first generation with this scenario.

MATCH(p:Pokemon{name:'eevee'})-[:evolves_to]-(e:Pokemon)
RETURN p,e

The result illustrates a very clear view of each evolution path for Eevee. === Types The initial data load also included type relationships between different Pokemon. Each Pokemon can have between 1 and 2 types. The data set manages these by using type1 and type2 relationships. Sticking with the Eevee example, the query below will add Type information to the graph.

MATCH(p1:Pokemon{name:'eevee'})-[:type1]-(t1:Type)
MATCH(p1)-[:evolves_to]-(e1:Pokemon)-[:type1|type2]-(t2:Type)
RETURN p1,e1,t1,t2

The result is similar to the previous graph with the addition of Pokemon types. As an added bonus it also shows type advantages and disadvantages of the Pokemon Eevee can evolve into. This proves useful by adding another unrelated Pokemon type.

The query below adds ground type to the graph. In the hypothetical situation where a trainer wants to base their Eevee evolution path on an upcoming battle against a ground type Pokemon, this graph shows clearly (with a little bit of dragging) the advantages and disadvantages of each path.

MATCH(p1:Pokemon{name:'eevee'})-[:type1]-(t1:Type)
MATCH(p1)-[:evolves_to]-(e1:Pokemon)-[:type1|type2]-(t2:Type)
MATCH(t3:Type{name:'ground'})
return p1,t1,e1,t2,t3

Other Analysis

There are a few other attributes in the evolves_to relationships, with many more on the way that let us perform other interesting analysis on the evolution relationships.

This query will display any evolution which requires an item to evolve, along with the item name. Since the query didn’t specify to return nodes and relationships, rather properties, the result needs to be displayed in a table.

match(p1:Pokemon)-[r:evolves_to]-(p2:Pokemon)
where r.trigger= 'use_item'
return p2.name, r.item, p1.name

PokemonGO (experimental stages)

There is currently experimental PokemonGO support. The following query generates a graph showing the full trail of any evolution that requires 100 or more candies. It’s important to note that the full trail is displayed, so an evolution relationship like Dragonair → Dragonite will still show Dratini in the chain to give a full picture of the evolution. To exclude this just comment out line 2 and remove p1 from the return statement in the query below.

match(n:Pokemon)-[r:evolves_to]-(p)
match(p1)-[r1:evolves_to]-(p)
where r.pokemongo_candy >= 100
return n,p,p1

Console

About Me

Created by Sean Byrne - Data Engineer | LinkedIn - GitHub