In [19]:
import pandas as pd
import matplotlib.pyplot as plt
# Load the data from Google Sheets
url = 'https://docs.google.com/spreadsheets/d/1yhcZ3klzIASrM4EEhBsI2KbhYd7pzcUEkSj7ZoNoWMU/export?format=csv'
df = pd.read_csv(url)
# Clean column names
df.columns = df.columns.str.replace('\n', '')
# Lists to store information for each generation
regions = ['Kanto', 'Johto', 'Hoenn', 'Sinnoh', 'Unova', 'Kalos', 'Alola', 'Galar', 'Paldea']
generation_starts = [1, 152, 252, 387, 494, 650, 722, 810, 906]
generation_ends = [151, 251, 386, 493, 649, 721, 809, 905, 1008]
# Lists to store our results
avg_heights = []
pokemon_counts = []
tallest_names = []
tallest_heights = []
shortest_names = []
shortest_heights = []
# Go through each generation
for i in range(9):
gen_num = i + 1
start = generation_starts[i]
end = generation_ends[i]
# Find all pokemon in this generation
gen_pokemon = df[(df['NationalDex'] >= start) & (df['NationalDex'] <= end)]
# Count pokemon
count = len(gen_pokemon)
pokemon_counts.append(count)
# Calculate average height
heights = gen_pokemon['Height (m)'].dropna() # Remove missing values
if len(heights) > 0:
avg = heights.mean()
avg_heights.append(avg)
# Find tallest pokemon
max_height = heights.max()
tallest_row = gen_pokemon[gen_pokemon['Height (m)'] == max_height].iloc[0]
tallest_names.append(tallest_row['PokemonName'])
tallest_heights.append(max_height)
# Find shortest pokemon
min_height = heights.min()
shortest_row = gen_pokemon[gen_pokemon['Height (m)'] == min_height].iloc[0]
shortest_names.append(shortest_row['PokemonName'])
shortest_heights.append(min_height)
else:
avg_heights.append(0)
tallest_names.append("None")
tallest_heights.append(0)
shortest_names.append("None")
shortest_heights.append(0)
# Find the top 5 tallest and shortest Pokemon overall
# Remove rows with missing heights
df_with_heights = df.dropna(subset=['Height (m)'])
# Sort by height to get tallest
df_sorted_tall = df_with_heights.sort_values('Height (m)', ascending=False)
top_5_tallest = df_sorted_tall.head(5)
# Sort by height to get shortest
df_sorted_short = df_with_heights.sort_values('Height (m)', ascending=True)
top_5_shortest = df_sorted_short.head(5)
# Function to find which generation a Pokemon is from
def find_generation(dex_num):
for i in range(9):
if generation_starts[i] <= dex_num <= generation_ends[i]:
return i + 1
return 0
# Calculate overall statistics
all_heights = df['Height (m)'].dropna()
overall_avg = all_heights.mean()
# Print overall statistics
print("=" * 60)
print("TOP 5 TALLEST POKEMON ACROSS ALL GENERATIONS")
print("=" * 60)
rank = 1
for index, pokemon in top_5_tallest.iterrows():
gen = find_generation(pokemon['NationalDex'])
print(f"\n#{rank}: {pokemon['PokemonName']}")
print(f" Height: {pokemon['Height (m)']}m")
print(f" National Dex #: {int(pokemon['NationalDex'])}")
print(f" Generation: {gen} ({regions[gen-1]})")
rank += 1
print("\n" + "=" * 60)
print("TOP 5 SHORTEST POKEMON ACROSS ALL GENERATIONS")
print("=" * 60)
rank = 1
for index, pokemon in top_5_shortest.iterrows():
gen = find_generation(pokemon['NationalDex'])
print(f"\n#{rank}: {pokemon['PokemonName']}")
print(f" Height: {pokemon['Height (m)']}m")
print(f" National Dex #: {int(pokemon['NationalDex'])}")
print(f" Generation: {gen} ({regions[gen-1]})")
rank += 1
print(f"\n" + "=" * 60)
print("OVERALL STATISTICS")
print("=" * 60)
print(f"Overall Average Height: {overall_avg:.2f}m")
print(f"Total Pokemon with Height Data: {len(all_heights)}")
height_difference = top_5_tallest.iloc[0]['Height (m)'] - top_5_shortest.iloc[0]['Height (m)']
print(f"Height difference between tallest and shortest: {height_difference:.2f}m")
print(f"The tallest Pokemon is {top_5_tallest.iloc[0]['Height (m)']/top_5_shortest.iloc[0]['Height (m)']:.1f}x taller than the shortest!")
# Print the results by generation
print("\n" + "=" * 60)
print("GENERATION-BY-GENERATION ANALYSIS")
print("=" * 60)
for i in range(9):
print(f"\nGeneration {i+1} ({regions[i]}):")
print(f"Number of Pokemon: {pokemon_counts[i]}")
print(f"Average Height: {avg_heights[i]:.2f}m")
print(f"Tallest: {tallest_names[i]} ({tallest_heights[i]}m)")
print(f"Shortest: {shortest_names[i]} ({shortest_heights[i]}m)")
# Make a bar chart
plt.figure(figsize=(12, 8))
plt.subplot(2, 1, 1)
generations = list(range(1, 10))
bars = plt.bar(generations, avg_heights)
plt.title('Average Pokemon Height by Generation')
plt.xlabel('Generation')
plt.ylabel('Average Height (meters)')
# Add a horizontal line for overall average
plt.axhline(y=overall_avg, color='red', linestyle='--',
label=f'Overall Average: {overall_avg:.2f}m')
plt.legend()
# Add labels on the bars
for i, bar in enumerate(bars):
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2, height,
f'{height:.2f}m', ha='center', va='bottom')
# Count pokemon by size
# tiny: 0-1m, small: 1-2m, medium: 2-4m, large: 4-8m, huge: 8m+
plt.subplot(2, 1, 2)
# Lists for each size category
tiny_counts = []
small_counts = []
medium_counts = []
large_counts = []
huge_counts = []
for i in range(9):
start = generation_starts[i]
end = generation_ends[i]
# Get pokemon for this generation
gen_pokemon = df[(df['NationalDex'] >= start) & (df['NationalDex'] <= end)]
# Count pokemon in each size category
tiny = len(gen_pokemon[(gen_pokemon['Height (m)'] >= 0) & (gen_pokemon['Height (m)'] < 1)])
small = len(gen_pokemon[(gen_pokemon['Height (m)'] >= 1) & (gen_pokemon['Height (m)'] < 2)])
medium = len(gen_pokemon[(gen_pokemon['Height (m)'] >= 2) & (gen_pokemon['Height (m)'] < 4)])
large = len(gen_pokemon[(gen_pokemon['Height (m)'] >= 4) & (gen_pokemon['Height (m)'] < 8)])
huge = len(gen_pokemon[gen_pokemon['Height (m)'] >= 8])
tiny_counts.append(tiny)
small_counts.append(small)
medium_counts.append(medium)
large_counts.append(large)
huge_counts.append(huge)
# Make stacked bar chart
width = 0.8
plt.bar(generations, tiny_counts, width, label='tiny')
plt.bar(generations, small_counts, width, bottom=tiny_counts, label='small')
# Calculate bottoms for stacking
bottom_for_medium = [tiny_counts[i] + small_counts[i] for i in range(9)]
plt.bar(generations, medium_counts, width, bottom=bottom_for_medium, label='medium')
bottom_for_large = [bottom_for_medium[i] + medium_counts[i] for i in range(9)]
plt.bar(generations, large_counts, width, bottom=bottom_for_large, label='large')
bottom_for_huge = [bottom_for_large[i] + large_counts[i] for i in range(9)]
plt.bar(generations, huge_counts, width, bottom=bottom_for_huge, label='huge')
plt.title('Pokemon Size Distribution by Generation')
plt.xlabel('Generation')
plt.ylabel('Number of Pokemon')
plt.legend()
plt.tight_layout()
plt.show()
# Print size distribution percentages
print("\n" + "=" * 60)
print("HEIGHT DISTRIBUTION STATISTICS")
print("=" * 60)
size_names = ['Tiny (0-1m)', 'Small (1-2m)', 'Medium (2-4m)', 'Large (4-8m)', 'Huge (8m+)']
all_counts = [tiny_counts, small_counts, medium_counts, large_counts, huge_counts]
for j, size_name in enumerate(size_names):
print(f"\n{size_name}:")
for i in range(9):
count = all_counts[j][i]
total = pokemon_counts[i]
if total > 0:
percentage = (count / total) * 100
else:
percentage = 0
print(f"Gen {i+1}: {count} Pokemon ({percentage:.1f}%)")
# Print fun facts at the end
print("\n" + "=" * 60)
print("FUN HEIGHT FACTS")
print("=" * 60)
# Find which generation has the most giants and tiny Pokemon
max_huge = max(huge_counts)
max_tiny = max(tiny_counts)
gen_with_most_huge = huge_counts.index(max_huge) + 1
gen_with_most_tiny = tiny_counts.index(max_tiny) + 1
print(f"Generation with most huge Pokemon (8m+): Gen {gen_with_most_huge} with {max_huge} Pokemon")
print(f"Generation with most tiny Pokemon (0-1m): Gen {gen_with_most_tiny} with {max_tiny} Pokemon")
# Find how many Pokemon are taller than average
taller_than_avg = len(df[df['Height (m)'] > overall_avg])
shorter_than_avg = len(df[df['Height (m)'] < overall_avg])
print(f"\nPokemon taller than average ({overall_avg:.2f}m): {taller_than_avg}")
print(f"Pokemon shorter than average: {shorter_than_avg}")
============================================================ TOP 5 TALLEST POKEMON ACROSS ALL GENERATIONS ============================================================ #1: Eternatus Height: 20.0m National Dex #: 890 Generation: 8 (Galar) #2: Wailord Height: 14.5m National Dex #: 321 Generation: 3 (Hoenn) #3: Dondozo Height: 12.0m National Dex #: 977 Generation: 9 (Paldea) #4: Exeggutor (Alolan) Height: 10.9m National Dex #: 103 Generation: 1 (Kanto) #5: Steelix (Mega) Height: 10.5m National Dex #: 208 Generation: 2 (Johto) ============================================================ TOP 5 SHORTEST POKEMON ACROSS ALL GENERATIONS ============================================================ #1: Ash-Greninja Height: 0.0m National Dex #: 658 Generation: 6 (Kalos) #2: Gimmighoul (Roaming) Height: 0.1m National Dex #: 999 Generation: 9 (Paldea) #3: Comfey Height: 0.1m National Dex #: 764 Generation: 7 (Alola) #4: Flabébé Height: 0.1m National Dex #: 669 Generation: 6 (Kalos) #5: Cutiefly Height: 0.1m National Dex #: 742 Generation: 7 (Alola) ============================================================ OVERALL STATISTICS ============================================================ Overall Average Height: 1.28m Total Pokemon with Height Data: 1214 Height difference between tallest and shortest: 20.00m The tallest Pokemon is infx taller than the shortest! ============================================================ GENERATION-BY-GENERATION ANALYSIS ============================================================ Generation 1 (Kanto): Number of Pokemon: 202 Average Height: 1.30m Tallest: Exeggutor (Alolan) (10.9m) Shortest: Diglett (0.2m) Generation 2 (Johto): Number of Pokemon: 112 Average Height: 1.27m Tallest: Steelix (Mega) (10.5m) Shortest: Natu (0.2m) Generation 3 (Hoenn): Number of Pokemon: 162 Average Height: 1.37m Tallest: Wailord (14.5m) Shortest: Azurill (0.2m) Generation 4 (Sinnoh): Number of Pokemon: 128 Average Height: 1.21m Tallest: Dialga (Origin) (7.0m) Shortest: Budew (0.2m) Generation 5 (Unova): Number of Pokemon: 179 Average Height: 1.08m Tallest: Kyurem (White) (3.6m) Shortest: Joltik (0.1m) Generation 6 (Kalos): Number of Pokemon: 96 Average Height: 1.16m Tallest: Hoopa (Unbound) (6.5m) Shortest: Ash-Greninja (0.0m) Generation 7 (Alola): Number of Pokemon: 107 Average Height: 1.42m Tallest: Celesteela (9.2m) Shortest: Cutiefly (0.1m) Generation 8 (Galar): Number of Pokemon: 111 Average Height: 1.44m Tallest: Eternatus (20.0m) Shortest: Sinistea (0.1m) Generation 9 (Paldea): Number of Pokemon: 113 Average Height: 1.29m Tallest: Dondozo (12.0m) Shortest: Gimmighoul (Roaming) (0.1m)
C:\Users\Tony\AppData\Local\Temp\ipykernel_16212\2101290192.py:116: RuntimeWarning: divide by zero encountered in scalar divide print(f"The tallest Pokemon is {top_5_tallest.iloc[0]['Height (m)']/top_5_shortest.iloc[0]['Height (m)']:.1f}x taller than the shortest!")
============================================================ HEIGHT DISTRIBUTION STATISTICS ============================================================ Tiny (0-1m): Gen 1: 73 Pokemon (36.1%) Gen 2: 56 Pokemon (50.0%) Gen 3: 73 Pokemon (45.1%) Gen 4: 66 Pokemon (51.6%) Gen 5: 84 Pokemon (46.9%) Gen 6: 48 Pokemon (50.0%) Gen 7: 57 Pokemon (53.3%) Gen 8: 51 Pokemon (45.9%) Gen 9: 51 Pokemon (45.1%) Small (1-2m): Gen 1: 105 Pokemon (52.0%) Gen 2: 44 Pokemon (39.3%) Gen 3: 67 Pokemon (41.4%) Gen 4: 45 Pokemon (35.2%) Gen 5: 81 Pokemon (45.3%) Gen 6: 38 Pokemon (39.6%) Gen 7: 28 Pokemon (26.2%) Gen 8: 32 Pokemon (28.8%) Gen 9: 44 Pokemon (38.9%) Medium (2-4m): Gen 1: 19 Pokemon (9.4%) Gen 2: 9 Pokemon (8.0%) Gen 3: 15 Pokemon (9.3%) Gen 4: 11 Pokemon (8.6%) Gen 5: 14 Pokemon (7.8%) Gen 6: 6 Pokemon (6.2%) Gen 7: 15 Pokemon (14.0%) Gen 8: 27 Pokemon (24.3%) Gen 9: 15 Pokemon (13.3%) Large (4-8m): Gen 1: 3 Pokemon (1.5%) Gen 2: 1 Pokemon (0.9%) Gen 3: 5 Pokemon (3.1%) Gen 4: 6 Pokemon (4.7%) Gen 5: 0 Pokemon (0.0%) Gen 6: 4 Pokemon (4.2%) Gen 7: 5 Pokemon (4.7%) Gen 8: 0 Pokemon (0.0%) Gen 9: 2 Pokemon (1.8%) Huge (8m+): Gen 1: 2 Pokemon (1.0%) Gen 2: 2 Pokemon (1.8%) Gen 3: 2 Pokemon (1.2%) Gen 4: 0 Pokemon (0.0%) Gen 5: 0 Pokemon (0.0%) Gen 6: 0 Pokemon (0.0%) Gen 7: 2 Pokemon (1.9%) Gen 8: 1 Pokemon (0.9%) Gen 9: 1 Pokemon (0.9%) ============================================================ FUN HEIGHT FACTS ============================================================ Generation with most huge Pokemon (8m+): Gen 1 with 2 Pokemon Generation with most tiny Pokemon (0-1m): Gen 5 with 84 Pokemon Pokemon taller than average (1.28m): 453 Pokemon shorter than average: 761
In [18]:
# Lists to store type information
type_names = []
type_total_heights = []
type_counts = []
type_tallest_names = []
type_tallest_heights = []
type_shortest_names = []
type_shortest_heights = []
# Get all unique types
all_types = set()
for _, pokemon in df.iterrows():
if pd.notna(pokemon['Type I']):
all_types.add(pokemon['Type I'])
if pd.notna(pokemon['Type II']):
all_types.add(pokemon['Type II'])
# Convert to sorted list
all_types = sorted(list(all_types))
# Calculate stats for each type
for poke_type in all_types:
heights_for_type = []
names_for_type = []
# Go through all Pokemon and find ones with this type
for _, pokemon in df.iterrows():
if pd.notna(pokemon['Height (m)']):
# Check if this Pokemon has our type
has_type = False
if pd.notna(pokemon['Type I']) and pokemon['Type I'] == poke_type:
has_type = True
if pd.notna(pokemon['Type II']) and pokemon['Type II'] == poke_type:
has_type = True
if has_type:
heights_for_type.append(pokemon['Height (m)'])
names_for_type.append(pokemon['PokemonName'])
# Calculate statistics for this type
if len(heights_for_type) > 0:
type_names.append(poke_type)
type_counts.append(len(heights_for_type))
# Average
avg = sum(heights_for_type) / len(heights_for_type)
type_total_heights.append(avg)
# Find tallest
max_height = max(heights_for_type)
max_index = heights_for_type.index(max_height)
type_tallest_names.append(names_for_type[max_index])
type_tallest_heights.append(max_height)
# Find shortest
min_height = min(heights_for_type)
min_index = heights_for_type.index(min_height)
type_shortest_names.append(names_for_type[min_index])
type_shortest_heights.append(min_height)
# Sort types by average height using bubble sort (beginner-friendly)
for i in range(len(type_names)):
for j in range(0, len(type_names) - i - 1):
if type_total_heights[j] > type_total_heights[j + 1]:
# Swap all related lists
type_names[j], type_names[j + 1] = type_names[j + 1], type_names[j]
type_total_heights[j], type_total_heights[j + 1] = type_total_heights[j + 1], type_total_heights[j]
type_counts[j], type_counts[j + 1] = type_counts[j + 1], type_counts[j]
type_tallest_names[j], type_tallest_names[j + 1] = type_tallest_names[j + 1], type_tallest_names[j]
type_tallest_heights[j], type_tallest_heights[j + 1] = type_tallest_heights[j + 1], type_tallest_heights[j]
type_shortest_names[j], type_shortest_names[j + 1] = type_shortest_names[j + 1], type_shortest_names[j]
type_shortest_heights[j], type_shortest_heights[j + 1] = type_shortest_heights[j + 1], type_shortest_heights[j]
# Print results
print("\n" + "=" * 80)
print("POKEMON TYPES SORTED BY AVERAGE HEIGHT (SHORTEST TO TALLEST)")
print("=" * 80)
for i in range(len(type_names)):
print(f"\n{type_names[i]} Type:")
print(f" Average Height: {type_total_heights[i]:.2f}m")
print(f" Number of Pokemon: {type_counts[i]}")
print(f" Shortest: {type_shortest_names[i]} ({type_shortest_heights[i]:.2f}m)")
print(f" Tallest: {type_tallest_names[i]} ({type_tallest_heights[i]:.2f}m)")
# Create bar chart
plt.figure(figsize=(15, 8))
bars = plt.bar(type_names, type_total_heights)
plt.xticks(rotation=45, ha='right')
plt.title('Average Pokemon Height by Type')
plt.xlabel('Type')
plt.ylabel('Average Height (meters)')
# Add labels on bars
for i, bar in enumerate(bars):
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2, height,
f'{height:.2f}m', ha='center', va='bottom')
plt.tight_layout()
plt.show()
================================================================================ POKEMON TYPES SORTED BY AVERAGE HEIGHT (SHORTEST TO TALLEST) ================================================================================ Fairy Type: Average Height: 0.91m Number of Pokemon: 79 Shortest: Flabébé (0.10m) Tallest: Weezing (Galarian) (3.00m) Bug Type: Average Height: 0.94m Number of Pokemon: 108 Shortest: Joltik (0.10m) Tallest: Slither Wing (3.20m) Electric Type: Average Height: 1.02m Number of Pokemon: 85 Shortest: Joltik (0.10m) Tallest: Xurkitree (3.80m) Normal Type: Average Height: 1.03m Number of Pokemon: 151 Shortest: Azurill (0.20m) Tallest: Dudunsparce (Three Segment) (4.50m) Grass Type: Average Height: 1.03m Number of Pokemon: 141 Shortest: Budew (0.20m) Tallest: Exeggutor (Alolan) (10.90m) Rock Type: Average Height: 1.23m Number of Pokemon: 92 Shortest: Dwebble (0.30m) Tallest: Onix (8.80m) Fire Type: Average Height: 1.24m Number of Pokemon: 95 Shortest: Castform (Sunny) (0.30m) Tallest: Groudon (Primal) (5.00m) Flying Type: Average Height: 1.31m Number of Pokemon: 146 Shortest: Natu (0.20m) Tallest: Celesteela (9.20m) Ghost Type: Average Height: 1.34m Number of Pokemon: 84 Shortest: Sinistea (0.10m) Tallest: Giratina (Origin) (6.90m) Psychic Type: Average Height: 1.34m Number of Pokemon: 130 Shortest: Cosmoem (0.10m) Tallest: Necrozma (Ultra) (7.50m) Dark Type: Average Height: 1.36m Number of Pokemon: 89 Shortest: Ash-Greninja (0.00m) Tallest: Gyarados (Mega) (6.50m) Poison Type: Average Height: 1.36m Number of Pokemon: 91 Shortest: Budew (0.20m) Tallest: Eternatus (20.00m) Fighting Type: Average Height: 1.40m Number of Pokemon: 90 Shortest: Pawmo (0.40m) Tallest: Slither Wing (3.20m) Water Type: Average Height: 1.44m Number of Pokemon: 175 Shortest: Ash-Greninja (0.00m) Tallest: Wailord (14.50m) Ice Type: Average Height: 1.49m Number of Pokemon: 65 Shortest: Castform (Snowy) (0.30m) Tallest: Cetitan (4.50m) Ground Type: Average Height: 1.67m Number of Pokemon: 90 Shortest: Diglett (0.20m) Tallest: Steelix (Mega) (10.50m) Steel Type: Average Height: 1.71m Number of Pokemon: 84 Shortest: Diglett (Alolan) (0.20m) Tallest: Steelix (Mega) (10.50m) Dragon Type: Average Height: 2.54m Number of Pokemon: 86 Shortest: Applin (0.20m) Tallest: Eternatus (20.00m)