"""
# Video game success EDA 
"""
"""
In this document, I tried to conduct a visual analysis of data from video game datasets.


"""
"""
I hope you like what I did, I will be glad to comments.

I judged the data not biased, as at the moment I have a ps5, xbox series s, nintendo switch and nintendo 3ds, yes, it's a bit overkill, but I like it)
"""
"""
# Importing libraries
"""
import math
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import datetime
import seaborn as sns
import re
import warnings
from scipy import stats as st
import matplotlib.lines as mlines

warnings.filterwarnings('ignore')
"""
# Local functions
"""
"""
**The description of the functions is written in Russian for an obvious reason - I'm from Russia)**
"""
def fills_good(data, main_column, function, group_columns):
    """Функция заполнения пропущенных значений

    Для использования функции необходимо передать ей
    следующие аргументы:
    
    data - массив данных, в котором необходимо заполнить пропуски;
    main_column - столбец в котором пропущены значения;
    function - значение функции, которая будет применяться при
         заполнении пустых значений в кавычках ('mean','median'...);
    group_columns - столбцы для группировки данных в виде массива [...] 
         заполнение пропусков будет производиться в соответствии
         с группировкой по указанным столбцам.
    """
    
    data[main_column] = data[main_column].fillna(data.groupby(group_columns)[main_column].transform(function))
    
def pre_research(data, column, range_min=0, range_max=0, clr='blue'):
    """Функция предварительного анализа данных
    Данная функция выведет уникальные значения указанного
    столбца и построит гистограмму.

    Для использования функции необходимо передать ей
    следующие аргументы:
    
    data - массив данных, которые нужно анализировать;
    column - название столбца, по которому проводится анализ;
    range_min, range_max - минимальное и максимальное
        граничные значения, выводимые на гистограмму
        по умолчанию задаются минимумом и максимумом значений столбца, 
        при необходимости можно внести нужные занчения для 
        масштабирования гистограммы.
    clr - цвет гистограммы.
    """
    
    print(f'1% percentile: {data[column].quantile(.1)}')
    print(f'50% percentile: {data[column].quantile(.50)}')
    print(f'99% percentile: {data[column].quantile(.99)}')
    # В столбце есть выбросы значений, построим гистограмму для того, 
    # чтобы понять как часто встречаются большие и очень малые значения
    data1 = data.copy()
    fig = plt.figure(figsize=(15, 6)) 
    if range_min==range_max:
        range_min = data[column].min()
        range_max = data[column].max()
    else:
        data1 = data1[data1[column]<data1[column].quantile(range_max)]
        data1 =  data1[data1[column]>data1[column].quantile(range_min)]
    
    sns.histplot(data1[column], kde=True, bins=len(data1[column].unique()), color=clr)
    plt.title(f"{column} histogram")
    plt.ylabel(f"{column} count")
    plt.xlabel(column)

    plt.show()
    

def print_hist(series,bins, title):
    """Функция построения гистограммы

    Для использования функции необходимо передать ей
    следующие аргументы:
    
    series - столбец данных для построения гистограммы;
    bins - количесттво корзин;
    title - название графика.
    
        Для улучшения визуализации распределения данных
    минимальное и максимальное значения для построения
    считаются по 1 и 99му персентилю
    """   
    
    fig = plt.figure(figsize=(15, 6)) 
    min_range = series.quantile(.1)
    max_range = series.quantile(.99)
    hist = plt.hist(series, bins, range = (min_range,max_range))
    grid1 = plt.grid(True)
    plt.title(title)
    plt.show()
    print(f'Mean value: {round(series.mean(),2)}')
    print(f'Median value: {round(series.median(),2)}')
    

def print_matrix(data, sub_columns, min_size=9, max_size=9):
    """Функция построения матрицы диаграмм рассеяния

    Для использования функции необходимо передать ей
    следующие аргументы:
    
    data - массив исходных данных;
    main_column - основной столбец данных, относительно которого будет
        проводиться анализ - 'название_столбца';
    sub_columns - вспомогательные столбцы, влияние которых на
        основной столбец мы оцениваем - ['1','2','3',...];
    min_size, max_size - минимальное и максимальное значение размера
        каждой ячейки матрицы в дюймах (по умолчанию - 9 дюймов).
    """
    
    #pivot_data = data.pivot_table(index = main_column, 
    #                        values = sub_columns)
    pivot_data = data[sub_columns]
    pd.plotting.scatter_matrix(pivot_data, diagonal = 'kde',figsize=(min_size, max_size)) 

def print_scatter(data, x, y, labels, clr = "g", min_size=15, max_size=8):
    """Функция построения диаграмм рассеяния

    Для использования функции необходимо передать ей
    следующие аргументы:
    
    data - массив исходных данных;
    x, y - названия столбцов, относительно которых будет
        проводиться анализ - 'название_столбца';
    labels - массив названий диаграммы и осей - ['Заголовок','x_name','y_name'];
    clr - цвет точек;
    min_size, max_size - минимальное и максимальное значение размера
        каждой ячейки матрицы в дюймах (по умолчанию - 9 дюймов).
    """
    
    plt.figure(figsize=(min_size, max_size)) 
    plt.scatter( x, y, data=data,alpha=0.2,color=clr)
    plt.title(labels[0],fontsize=15)
    plt.xlabel(labels[1],fontsize=13)
    plt.ylabel(labels[2],fontsize=13)
    plt.grid()
    plt.show()
    
def print_plt_lines(data, categ_column, x, y, lines, labels=['','','']):
    """Функция построения нескольких линейных графиков на одних координатах

    Для использования функции необходимо передать ей
    следующие аргументы:
    
    data - массив исходных данных;
    x, y - названия столбцов, относительно которых будет
        проводиться анализ - 'название_столбца';
    lines - массив названий категориальных данных - ['name1','name2','name3'.....];
    labels - массив названий категориальных данных - ['Заголовок','x_name','y_name'];

    """
    
    fig = plt.figure(figsize=(15, 6)) 
    for i in lines:
        plot_data = data[data[categ_column]==i]
        plt.plot( 
            plot_data[x],
            plot_data[y], 
            linestyle= '-', 
#             marker='o',
            linewidth=2, 
            alpha=0.9,
            )
    plt.grid(True)
    plt.title(labels[0])
    plt.xlabel(labels[1])
    plt.ylabel(labels[2])
    plt.legend(lines)
    plt.show()

    
def lolipop_plot(data, y, x,labels, color1='orange', color2='gray', color_lim=150):
    """Функция построения Lolipop графиков:

    Для использования функции необходимо передать ей
    следующие аргументы:
    
    data - массив исходных данных;
    x, y - названия столбцов, относительно которых будет
        проводиться анализ - 'название_столбца';
    labels - массив названий категориальных данных - ['Заголовок','x_name','y_name'];
    color1 - цвет первого выделения, по умолчанию - 'orange';
    color2 - цвет второго выделения, по умолчанию - 'gray'; 
    color_lim - граница изменения цвета по оси Х, по умолчанию - 150.

    """
    
    
    data = data.sort_values(by = y)
    
    my_range=range(1,len(data.index)+1)
    my_color=np.where(data[y] > color_lim, color1, color2)
    fig = plt.figure(figsize=(15, 6)) 
    plt.hlines(y=my_range, xmin=0, xmax=data[y], color=my_color)
    plt.scatter(data[y], my_range, color=my_color, alpha=1)
    plt.yticks(my_range, data[x])
    plt.title(labels[0])
    plt.xlabel(labels[1])
    plt.ylabel(labels[2])
    plt.grid()
    plt.show()
"""
# Exploring data from a files
"""
"""
## Data description
"""
"""
    Name — the name of the game
    Platform — videogame platform
    year — year of release
    Genre — genre of the game
    NA_sales — sales in North America
    EU_sales — sales in Europe
    JP_sales — sales in Japan
    Other_sales — sales in other countries (Russia for example)
    Critic_Score — critic score (maximum - 100)
    User_Score — user score (maximum - 10)
    Rating rating from the ESRB organization (eng. Entertainment Software Rating Board). This association determines the rating of computer games and assigns them a suitable age category.

The data is collected from two sets from kaggle, in the description above the columns that we will use in EDA
"""
"""
## Exploring data
"""
df_sales = pd.read_csv('../input/videogamesales/vgsales.csv')
df_sales['Name']
df_score = pd.read_csv('../input/video-game-sales-with-ratings/Video_Games_Sales_as_at_22_Dec_2016.csv')
df_score = df_score.rename({"Year_of_Release":"Year"}, axis=1)
df = df_score.merge(df_sales, how='left')
df.info()
df
"""
We will reduce the column names to lowercase:
"""
df.columns = df.columns.str.lower()
df
"""
At the stage of data preprocessing, the following changes must be made:

| col name        | Type replace           | Data gaps  |
| ------------- |:-------------:| -----:|
|  name     | not required | delete rows |
| platform	 | not required    |    not required |
| year	 | int    |   median replase |
| genre	 | not required    |    delete rows |
| na_sales	 | not required    |    not required |
| eu_sales	 | not required    |    not required |
| jp_sales	 | not required    |    not required |
| other_sales	 | not required    |    not required |
| critic_score	 | not required    |    not required |
| user_score	 | float    |    not required |
| rating	 | not required    |    fill- "no_rate" |
"""
"""
# Data preprocessing
"""
df = df.dropna(subset=['name'])
fills_good(df, 'year', 'median', 'platform')
df['year'] = df['year'].astype('int')
pre_research(df, 'year', clr='orange')
"""
In 2007-2010, there was a noticeable surge in the game development market
"""
pre_research(df, 'na_sales', range_max=0.99, clr='cyan')
"""
Let's see which games are knocked out for the 999th percentile
"""
df.loc[df['na_sales'] > df['na_sales'].quantile(.999)]
"""
No emissions, all games are real mastodons of the market. Most of them are from Nintendo, who would doubt it)
"""
pre_research(df, 'eu_sales', range_max=0.99, clr='blue')
pre_research(df, 'jp_sales', range_max=0.99, clr='red')
pre_research(df, 'other_sales', range_max=0.99, clr='olive')
pre_research(df, 'critic_score', clr='green')
"""
There are tbd values in the data of the 'user_score' column, according to the metacritic site tbd is an insufficient number of ratings (below 4x), so we will replace these values in the column with NaN
"""
df.loc[df['user_score']=='tbd','user_score'] = np.nan
df['user_score'] = df['user_score'].astype('float')

# Let's bring the user ratings to the same scale as the critics' ratings

df['user_score'] = df['user_score']*10
pre_research(df, 'user_score', clr='purple')
df['rating'] = df['rating'].fillna('no_rate')
df
df['sum_sales'] = df[['na_sales','eu_sales','jp_sales','other_sales']].sum(axis=1)
df
"""
# Research data analysis
"""
"""
Let's look at how many games were released in different years.
"""
pre_research(df, 'year')
df.groupby('year')['year'].count()

"""
We will not take into account the data below 1995 in the EDA, at that time there was the first noticeable growth of the gaming industry, which is most likely associated with the widespread distribution of CDs and consoles
"""
df = df.query('year >= 1995').copy()
"""
Let's see how sales by platform have changed. Select the platforms with the highest total sales and build a distribution by year. For what characteristic period of time do new platforms appear and old ones disappear?
"""
df_sales_by_year = df.pivot_table(index = ['year',
                                           'platform'], 
                                  values = 'sum_sales', 
                                  aggfunc = 'sum').reset_index()
df_sales_by_year

"""
We calculate the lifetime of different gaming platforms
"""
df_sales_by_year.groupby('platform')['platform'].count().sort_values(ascending = False)
df_sales_by_year.groupby('platform')['sum_sales'].sum().sort_values(ascending = False)
"""
-------------
We will build various graphs to visualize and compare the indicators of different platforms
"""
labels = ['Total sales of PlayStation and PC games by year',
          'Year',
          'Number of games sold, mln.',
          ]
print_plt_lines(df_sales_by_year, 
                'platform', 
                'year', 
                'sum_sales', 
                ['PS', 
                 'PS2', 
                 'PS3', 
                 'PS4', 
                 'PSP',
                 'PSV',
                 'PC',],
               labels)
"""
The graph shows that the previous generation of PS consoles is supported from 4 to 6 years

The peak of the number of copies of games sold on this platform = 2001-2005, just a year after the release of ps2, when video game manufacturers fully began to master the new hardware, in these years there were continuations of already iconic titles from ps1, as well as new games that later received sequels on new generations of consoles

PSP and PSVita are portable consoles, it is not surprising that the sales charts of these consoles are lower than the rest of the charts

PS Vita - Sony's most failed console
"""
labels = ['Total sales of games on Xbox and PC platforms by year',
          'Year',
          'Number of games sold, mln.',
          ]
print_plt_lines(df_sales_by_year, 
                'platform', 
                'year', 
                'sum_sales', 
                [ 'XB', 
                 'X360',
                 'XOne',
                 'PC',
                ],
               labels)
"""
Microsoft entered the video game industry in 2000 with a competitor to the Playstation 2 console in the Xbox video.

From the graphs, we can conclude about the colossal success in terms of selling Xbox 360 console games compared to the previous console, it's too early to judge sales on the new Xbox One console for 2014, but the dynamics of the first years of sales are not encouraging.

Xbox consoles are supported for 4 years after the release of the new version
"""
labels = ['Total sales of games on the Nintendo and PC platforms by year',
          'Year',
          'Number of games sold, mln.',
          ]
print_plt_lines(df_sales_by_year, 
                'platform', 
                'year', 
                'sum_sales', 
                [ 'GB', 
                 'SNES',
                 'N64',
                 'Wii',
                 'WiiU',
                 'GC',
                 'DS','PC',
                ],
               labels)
"""
Nintendo consoles are clearly different from Xbox and PS, they released gaming consoles before 1995 and occupied their niche market with exclusive game series that fans of this company loved.

We also see that the cycle of production of Nintendo consoles is very different from competitors and the life cycle of each console of this company is unique

It is worth noting that the Nintendo DS console is a portable console, it should be taken into account only in comparison with other portable consoles, since most titles for this type of device come out at their own prices and are exclusive.
"""
"""
Let's compare the sales of games on stationary consoles Nintendo, Xbox and PS, as well as on PC.
"""
labels = ['Total sales of games on the Nintendo, Xbox, PS and PC platforms by year',
          'Year',
          'Number of games sold, mln.',
          ]
print_plt_lines(df_sales_by_year, 
                'platform', 
                'year', 
                'sum_sales', 
                [ 'PS', 
                 'PS2', 
                 'PS3', 
                 'PS4', 
                 'XB', 
                 'X360',
                 'XOne',
                 'Wii',
                 'WiiU',
                 'PC',
                ],
               labels)
"""
in 2005-2010, the Xbox 360 console was clearly ahead of its competitor in terms of game sales, this is due to the fact that Microsoft released its console a year earlier and the cost of the console was lower than the cost of the PS3. 

There were also few good titles in the launch line of PS3 games, and the Xbox360 console had both new games and compatibility with old games and discs.

By 2010, Sony had already managed to release a sufficient number of exclusive games, which allowed it to outpace competitors in sales of games on the console.

If we compare the sales charts of games on the new generation of consoles, it is clearly visible that the PlayStation 4 console is 2 times ahead of the Xbox One console in sales in 2014-2016 (even if the fir provided incomplete data for 2016)

Personal computers have been lagging behind in terms of game sales for all years, most likely this is due to the ease of piracy on this type of device
"""
"""
----------------------
From the data considered, we can determine the actual period for the study.

We will consider the video game market in accordance with the past and current generation of consoles, i.e. since 2004, as well as limit the choice of data 

Let's divide our data into 2 categories: stationary and portable consoles

Stationary: 'PS3', 'PS4', 'X360','XOne', 'Wii', 'WiiU', as well as 'PC'

Portable: 'DS', 'PSP', 'PSV'


Let's highlight the corresponding graphs in the table and set a mark on the portability of consoles for convenience
"""
df_sales_by_year = df_sales_by_year.query('(year >=2004)&(platform in ["PS3","PS4", "X360","XOne", "Wii", "WiiU", "PC","DS", "PSP", "PSV"])')
df_sales_by_year['portable'] = 0
df_sales_by_year.loc[df_sales_by_year['platform'].apply(lambda x:x in [ 'DS', 'PSP', 'PSV']), 'portable'] = 1
"""
Let's build a graph for stationary consoles
"""
labels = ['Total sales of games on the Nintendo, Xbox, PS and PC platforms by year',
          'Year',
          'м',
          ]
print_plt_lines(df_sales_by_year.query('year >=2005'), 
                'platform', 
                'year', 
                'sum_sales', 
                [ 'PS3', 'PS4', 'X360','XOne', 'Wii', 'WiiU', 'PC',
                ],
               labels)
"""
Let's build a graph for portable consoles
"""
labels = ['Total sales of games on portable consoles by year',
          'Year',
          'Number of games sold, mln.',
          ]
print_plt_lines(df_sales_by_year, 
                'platform', 
                'year', 
                'sum_sales', 
                [ 'DS', 'PSP', 'PSV',
                ],
               labels)
"""
Consider the total sales for each gaming device for the entire period of life under consideration
"""
df_lolipop = df_sales_by_year.pivot_table(index = 'platform', 
                                          values = 'sum_sales', 
                                          aggfunc = 'sum').reset_index().sort_values(by = 'sum_sales')
df_lolipop['portable'] = 0
df_lolipop.loc[df_lolipop['platform'].apply(lambda x:x in [ 'DS', 'PSP', 'PSV']), 'portable'] = 1

my_range=range(1,len(df_lolipop.index)+1)
my_color=np.where(df_lolipop ['portable'] == 1, 'orange', 'green')
fig = plt.figure(figsize=(15, 6)) 
plt.hlines(y=my_range, xmin=0, xmax=df_lolipop['sum_sales'], color=my_color)
plt.scatter(df_lolipop['sum_sales'], my_range, color=my_color, alpha=1)
 

plt.yticks(my_range, df_lolipop['platform'])
plt.title("The total number of copies of games sold for the entire life cycle of the gaming device from 2005 to 2016.")
plt.xlabel('Number of copies of games sold, mln.')
plt.ylabel('Gaming device')
plt.grid()

# We make the legend manually, we will enter the notation for the lines

orange_line = mlines.Line2D([], [], color='orange', marker='o',
                          markersize=5, label='Portable console')
green_line = mlines.Line2D([], [], color='green', marker='o',
                          markersize=5, label='Stationary consoles and PCs')
plt.legend(handles=[green_line,orange_line],loc=4)
plt.show()
"""
From the graph of total sales of games on all gaming devices, it can be seen that in the previous generation, the Xbox 360 leads by a small margin, with a slight lag in 2nd and 3rd place, the PS3 and Wii consoles are located

Among portable consoles, the total dominance of the Nintendo DS is noticeable, the PSP sold more than 2 times fewer games over the same period of time, the PS Vita lags behind all gaming devices.

In the new generation of consoles, PS4 is currently leading, twice ahead of its competitor in the face of Xbox One, WiiU is also a lagging console, games for it are not in demand around the world.
"""
"""
Let's build the "Box with a mustache" graphs for the types of consoles under study, for this we will select them from our main data table
"""
stations = ['PS3', 'PS4', 'X360','XOne', 'Wii', 'WiiU', 'PC']
portable = ['DS', 'PSP', 'PSV']
all_platforms = stations + portable
past_gen = ['Wii', 'PS3', 'X360']
next_gen = ['WiiU', 'PS4', 'XOne']
main_df = df[df['platform'].apply(lambda x: x in all_platforms) ]
main_df['portable'] = 0
main_df.loc[main_df['platform'].apply(lambda x:x in [ 'DS', 'PSP', 'PSV']), 'portable'] = 1
fig = plt.figure(figsize=(15, 15)) 
ax = sns.boxplot(x='platform', y='sum_sales', data=main_df, palette='rainbow_r')
ax = sns.stripplot(x='platform', y='sum_sales', data=main_df, palette='plasma', jitter=0.2, size=2.5)
plt.title("Boxplot platform sales")
plt.grid()
plt.show()
"""
The Wii console has some kind of game that sold more than 80 million copies, we will cut off this value when plotting graphs, but we will take into account that this title cannot be ignored when planning a strategy, it is very popular, let's see what kind of game it is

"""
mega_title = main_df.query('sum_sales > 40')
mega_title
main_df_drop_wii_sports = main_df.query('sum_sales < 40')

fig = plt.figure(figsize=(15, 15)) 
ax = sns.boxplot(x='platform', y='sum_sales', data=main_df_drop_wii_sports, palette='rainbow_r')
ax = sns.stripplot(x='platform', y='sum_sales', data=main_df_drop_wii_sports, palette='plasma', jitter=0.2, size=2.5)
plt.title("Boxplot platform sales without wii sports")
plt.grid()
plt.show()
"""
Wii Sport was a so-called system seller, he used all the technological capabilities of the new Wii console controllers, which caused a boom in sales of this title and consoles, respectively

Let's build boxes with moustaches for different types of consoles:
"""
main_df_pg = main_df.query('sum_sales < 40')[main_df['platform'].apply(lambda x: x in past_gen)]

fig = plt.figure(figsize=(15, 15)) 
ax = sns.boxplot(x='platform', y='sum_sales', data=main_df_pg, palette='rainbow_r')
ax = sns.stripplot(x='platform', y='sum_sales', data=main_df_pg, palette='plasma', jitter=0.2, size=2.5)
plt.title("Boxplot for consoles of the last generation")
plt.xlabel('Game platform')
plt.ylabel('Number of copies of games sold')
plt.grid()
plt.show()
"""
From the graph, we can conclude that most of the games are sold in the amount of up to 3 million copies, we will limit the number of copies sold on the graph in order to examine the distribution in more detail
"""
main_df_pg = main_df.query('sum_sales < 5')[main_df['platform'].apply(lambda x: x in past_gen)]

fig = plt.figure(figsize=(15, 15)) 
ax = sns.boxplot(x='platform', y='sum_sales', data=main_df_pg, palette='rainbow_r')
ax = sns.stripplot(x='platform', y='sum_sales', data=main_df_pg, palette='plasma', jitter=0.2, size=2.5)
plt.title("Boxplot for consoles of the last generation ")
plt.xlabel('Game platform')
plt.ylabel('Number of copies of games sold')
plt.grid()
plt.show()
"""
It can be concluded that on Wii consoles, the distribution schedule is more compressed vertically, which means that most of the games sold are sold up to 1 million copies, in the case of Xbox 360 and PS3, we see that their sales spread is more vertically distributed, this is due to the fact that compared to Wii on the consoles in question, in addition to exclusive games, multiplatform games that simply do not exist on Wii are sold well
"""
"""
Let's build the same graphics for the new generation of consoles:
"""
main_df_ng = main_df.query('sum_sales < 5')[main_df['platform'].apply(lambda x: x in next_gen)]

fig = plt.figure(figsize=(15, 15)) 
ax = sns.boxplot(x='platform', y='sum_sales', data=main_df_ng, palette='rainbow_r')
ax = sns.stripplot(x='platform', y='sum_sales', data=main_df_ng, palette='plasma', jitter=0.2, size=2.5)
plt.title("Boxplot for consoles of the new generation ")
plt.xlabel('Game platform')
plt.ylabel('Number of copies of games sold')
plt.grid()
plt.show()
"""
The picture is the same, a little more games are sold for PS4, a little worse for Xbox One and WiiU games are sold much worse and even visually you can see how much less games are being developed for this platform (orange dots on the graph).

Unlike its predecessor, WiiU does not have a title in its arsenal that would sell this console and have sky-high sales, most likely this is a miscalculation by Nintendo.
"""
main_df_port = main_df.query('sum_sales < 40')[main_df['platform'].apply(lambda x: x in portable)]

fig = plt.figure(figsize=(15, 15)) 
ax = sns.boxplot(x='platform', y='sum_sales', data=main_df_port, palette='rainbow_r')
ax = sns.stripplot(x='platform', y='sum_sales', data=main_df_port, palette='plasma', jitter=0.2, size=2.5)
plt.title("Boxplot for consoles of the portable consoles")
plt.xlabel('Game platform')
plt.ylabel('Number of copies of games sold')
plt.grid()
plt.show()
"""
The Nintendo DS console has a lot of games that have sold more than 5 million copies, while both Sony consoles have almost no such games
"""
main_df_port = main_df.query('sum_sales < 2')[main_df['platform'].apply(lambda x: x in portable)]

fig = plt.figure(figsize=(15, 15)) 
ax = sns.boxplot(x='platform', y='sum_sales', data=main_df_port, palette='rainbow_r')
ax = sns.stripplot(x='platform', y='sum_sales', data=main_df_port, palette='plasma', jitter=0.2, size=2.5)
plt.title("Boxplot for consoles of the portable consoles")
plt.xlabel('Game platform')
plt.ylabel('Number of copies of games sold')
plt.grid()
plt.show()
"""
If you do not take into account the large titles of the Nintendo DS, it can be said that on average the PSP platform was almost as popular as the Nintendo DS

The PS Vita console can be considered a failure.
"""
"""
--------------------
"""
"""
Consider the impact of reviews from critics and users on the sale of games for various platforms, we will consider stationary consoles of the last generation:
"""
"""
Let's construct matrices of scattering diagrams
"""
data_to_plot = main_df.loc[main_df['platform'].apply(lambda x: x in next_gen),
                           ['na_sales',
                        'eu_sales',
                        'jp_sales',
                        'critic_score',
                        'user_score',
                        'platform']].sort_values(by='platform', ascending=True)
my_color={'PS4':'#3148FA', 'XOne':'#45DE6B','WiiU':'#FA737B'}
matrix_plot = sns.pairplot(data_to_plot,
                           hue="platform", 
                           kind='scatter', 
                           hue_order = ['PS4','XOne','WiiU'],
                           diag_kind='auto', 
                           palette=my_color,
                           plot_kws=dict(alpha=0.3),
                           diag_kws=dict(alpha=1, fill=False),
                          )
matrix_plot.fig.suptitle("Matrix of scattering diagrams for consoles of the current generation \n 2012-2016.", y = 1.05)
plt.show()

# In the data for this block, we will again remove the super popular Wii Sport game, we realized that it is fire, Nintendo fans will not be offended

data_to_plot = main_df.query('sum_sales < 40').loc[main_df['platform'].apply(lambda x: x in past_gen),
                           ['na_sales',
                        'eu_sales',
                        'jp_sales',
                        'critic_score',
                        'user_score',
                        'platform']].sort_values(by='platform', ascending=True)
my_color={'PS3':'#3148FA', 'X360':'#45DE6B','Wii':'#FA737B'}
matrix_plot = sns.pairplot(data_to_plot,
                           hue="platform", 
                           kind='scatter', 
                           hue_order = ['PS3','X360','Wii'],
                           diag_kind='auto', 
                           palette=my_color,
                           plot_kws=dict(alpha=0.3),
                           diag_kws=dict(alpha=1, fill=False),
                          )
matrix_plot.fig.suptitle("Matrix of scattering diagrams for consoles of the last generation \n 2005-2016.", y = 1.05)
plt.show()

data_to_plot = main_df.loc[main_df['platform'].apply(lambda x: x in portable),
                           ['na_sales',
                        'eu_sales',
                        'jp_sales',
                        'critic_score',
                        'user_score',
                        'platform']].sort_values(by='platform', ascending=True)
my_color={'PSP':'#3148FA', 'DS':'#45DE6B','PSV':'#FA737B'}
matrix_plot = sns.pairplot(data_to_plot,
                           hue="platform", 
                           kind='scatter', 
                           hue_order = ['DS','PSP','PSV'],
                           diag_kind='auto', 
                           palette=my_color,
                           plot_kws=dict(alpha=0.3),
                           diag_kws=dict(alpha=1, fill=False),
                          )
matrix_plot.fig.suptitle("Matrix of scattering diagrams for portable consoles of the last generation \n 2004-2016.", y = 1.05)
plt.show()
"""
From the presented scatter plot matrices, it can be concluded that critics' ratings have a greater impact on sales, or they correspond more to reality, because critics evaluate the game unbiasedly (ideally) and this is confirmed by the market, as well as vice versa, the market sees critics' ratings and buys the game more often. This trend can be traced on all platforms in all years.

About user ratings, we can say that on older platforms, their performance in comparison with sales tends to critics' ratings, but on new-generation consoles, gamers are hungry for games and, regardless of user ratings, sales of many games are large compared to other games in the same generation.
"""
"""
Let's calculate the Pearson correlation coefficients and build their visualization
"""
for i in all_platforms:
    corr = main_df.loc[main_df['platform']== i, 
                          ['year',
                           'sum_sales',
                           'critic_score',
                           'user_score']].corr()
    fig = plt.figure(figsize=(6, 5))
    sns.heatmap(corr, 
                annot=True, 
                annot_kws={"size": 11},
                cmap="BuGn"
               )
    plt.title(f"Correlation matrix for consoles {i}")
    plt.show()
"""
From the presented correlation matrices, the following conclusions can be drawn:
* For Xbox and Playstation consoles, critics' ratings are weak, but they affect the total sales of games;
* For the Wii console, critics' ratings do not affect total game sales;
* For all consoles, user ratings have almost no effect on total game sales;
* Critics' ratings and user ratings correlate noticeably more on controversial consoles than on widespread ones;
* On new-generation consoles, user ratings even have a negative correlation with sales, which confirms our conclusions regarding gaming hunger among gamers on new consoles.
----------------
"""
"""
Let's look at the general distribution of games by genre.
"""
df_genre_by_year = df.pivot_table(index=['genre','year'], 
                                  values='sum_sales',
                                 aggfunc = 'sum').reset_index()
df_genre_by_year['genre'].unique()
labels = ['Total sales of games by genre',
          'Year',
          'Number of games sold, mln.',
          ]
print_plt_lines(df_genre_by_year, 
                'genre', 
                'year', 
                'sum_sales', 
                [ 
       'Racing', 'Role-Playing', 'Shooter', 'Simulation', 'Sports',
       'Strategy'
                ],
               labels)
df_sales_by_year['platform'].unique()
labels = ['Total sales of games by genre',
 'Year',
 'Number of games sold, mln.',
          ]
print_plt_lines(df_genre_by_year, 
                'genre', 
                'year', 
                'sum_sales', 
                [ 'Action', 'Adventure', 'Fighting', 'Misc', 'Platform', 'Puzzle',
                ],
               labels)
"""
From the charts by year, you can select favorites - these are 'Action', 'Sports', 'Role-Playing', 'Misc', 'Shooter', let's make sure of this by building a Lolipop chart by genre:
"""
df_lolipop = df_genre_by_year.pivot_table(index = 'genre', 
                                          values = 'sum_sales', 
                                          aggfunc = 'sum').reset_index().sort_values(by = 'sum_sales')
labels = ['Total number of copies of games sold by genre from 2005 to 2016',
'Number of copies of games sold, million',
'Genre']
lolipop_plot(df_lolipop, 'sum_sales', 'genre',labels, color1='orange', color2='gray', color_lim=500)

"""
The graph shows that the games of the "Action" category have a large gap in sales from other genres, most likely such a jump is due to the fact that this is a fairly extensive genre and many games can be included in this category

The "Sports" genre owes its popularity to the previously reviewed Wii Sport

It is also possible to distinguish genres that are not popular - fighting games, simulators, adventures, strategies and puzzles, these are definitely niche genres of games, platformers could also be attributed to them, however, due to their diversity, platformers noticeably break ahead in sales and find their user
"""
"""
-------------------------
"""
"""
Let's form user portraits by region (NA, EU, JP), define:

     The most popular platforms (top 5). Describe the differences in sales shares.
     The most popular genres (top 5). Explain the difference.
     Does the ESRB rating affect sales in a particular region?
"""
df_lolipop
df_lolipop_platform = main_df.pivot_table(index = 'platform', 
                                          values = ['na_sales', 'eu_sales','jp_sales'],
                                          aggfunc = 'sum').reset_index().sort_values(by = 'na_sales')
labels = ['Total number of copies of games sold by platform type in North America from 2005 to 2016',
'Number of copies of games sold, million',
'Platform']
lolipop_plot(df_lolipop_platform, 'na_sales', 'platform',labels, color_lim=150)
print(df_lolipop_platform[['platform','na_sales']].sort_values(by='na_sales', ascending = False).reset_index())
labels = ['Total number of copies of games sold by platform type in Europe from 2005 to 2016',
'Number of copies of games sold, million',
'Platform']
lolipop_plot(df_lolipop_platform, 'eu_sales', 'platform',labels, color_lim=150)
print(df_lolipop_platform[['platform','eu_sales']].sort_values(by='eu_sales', ascending = False).reset_index())

labels = ['Total number of copies of games sold by platform type in Japan from 2005 to 2016',
'Number of copies of games sold, million',
'Platform']
lolipop_plot(df_lolipop_platform, 'jp_sales', 'platform',labels, color_lim=50)
print(df_lolipop_platform[['platform','jp_sales']].sort_values(by='jp_sales', ascending = False).reset_index())

"""
The differences between different markets are clearly visible. In Japan, they love Japanese consoles, in Europe they love everything, but they love PS more, in America they prefer American Xbox consoles, which are practically not used in Japan
"""
"""
-------------------
"""
"""
Consider the distribution by genre depending on the selected region:
"""
df_lolipop_genre = main_df.pivot_table(index = 'genre', 
                                          values = ['na_sales', 'eu_sales','jp_sales'],
                                          aggfunc = 'sum').reset_index().sort_values(by = 'na_sales')
labels = ['Total number of copies of games sold by genre in North America from 2005 to 2016',
'Number of copies of games sold, million',
'Platform']
lolipop_plot(df_lolipop_genre, 'na_sales', 'genre',labels, color_lim=150)
print(df_lolipop_genre[['genre','na_sales']].sort_values(by='na_sales', ascending = False).reset_index())
labels = ['Total number of copies of games sold by genre in Europe from 2005 to 2016',
'Number of copies of games sold, million',
'Platform']
lolipop_plot(df_lolipop_genre, 'eu_sales', 'genre',labels, color_lim=110)
print(df_lolipop_genre[['genre','eu_sales']].sort_values(by='eu_sales', ascending = False).reset_index())

labels = ['Total number of copies of games sold by genre in Japan from 2005 to 2016',
'Number of copies of games sold, million',
'Platform']
lolipop_plot(df_lolipop_genre, 'jp_sales', 'genre',labels, color_lim=25)
print(df_lolipop_genre[['genre','jp_sales']].sort_values(by='jp_sales', ascending = False).reset_index())

"""
There are genres that are popular all over the world: Action, Sports, RPG, but there are also outstanding values, for example, there are many platformer fans in Japan, this is due to the widespread use of portable consoles, platformers are most often played on them
"""
df_lolipop_rating = main_df.pivot_table(index = 'rating', 
                                          values = ['na_sales', 'eu_sales','jp_sales'],
                                          aggfunc = 'sum').reset_index().sort_values(by = 'na_sales')
labels = ['Total number of copies of games sold by ESRB rating in North America from 2005 to 2016',
'Number of copies of games sold, million',
'Rating']
lolipop_plot(df_lolipop_rating, 'na_sales', 'rating',labels, color_lim=400)
print(df_lolipop_rating[['rating','na_sales']].sort_values(by='na_sales', ascending = False).reset_index())
labels = ['Total number of copies of games sold by ESRB rating in Europe from 2005 to 2016',
'Number of copies of games sold, million',
'Rating']
lolipop_plot(df_lolipop_rating, 'eu_sales', 'rating',labels, color_lim=230)
print(df_lolipop_rating[['rating','eu_sales']].sort_values(by='eu_sales', ascending = False).reset_index())

labels = ['Total number of copies of games sold by ESRB rating in Japan from 2005 to 2016',
'Number of copies of games sold, million',
'Rating']
lolipop_plot(df_lolipop_rating, 'jp_sales', 'rating',labels, color_lim=50)
print(df_lolipop_rating[['rating','jp_sales']].sort_values(by='jp_sales', ascending = False).reset_index())
"""
"E" ("Everyone") — "For everyone": The content is quite suitable for the age category from 6 years. Such games may also appeal to adults. Games with this rating may contain minimal violence, mostly of a "cartoon" nature. The first game to receive this rating was The Simpsons Cartoon Studio, released in 1996. Originally "K-A" ("Kids to Adults")

"T" ("Teen") — "Teenagers": The game is suitable for people from 13 years old. Projects from this category may contain violence, obscene scenes, rude humor, moderately explicit sexual content, blood or infrequent use of profanity.

"M" ("Mature") — "For adults": The game materials are not suitable for teenagers under the age of 17. Projects with this rating may contain quite violent violence, a large amount of blood with dismemberment, obscene sex scenes or rude profanity that is undesirable for a younger audience. 

"""