<jupyter_start><jupyter_text>Визуализация данных<NAME>  FB: [fb.com/obulygin91](fb.com/obulygin91)  VK: [vk.com/obulygin91](vk.com/obulygin91)  LinkedIn: [linkedin.com/in/obulygin](linkedin.com/in/obulygin)  Telegram: @obulygin91  email: <EMAIL>    План- библиотека matplotlib  - библиотека seaborn- основные типы визуализаций Визуализация данных – это представление данных в виде, который обеспечивает наиболее эффективную работу человека по их изучению. Очень важный инструмент в рамках [EDA](https://en.wikipedia.org/wiki/Exploratory_data_analysis), который облегчает определение распределений, поиск аномалий, зависимостей, первичное выдвижение гипотез и пр. Важность визуализации может продемонстрировать [квартет Энскомба](https://en.wikipedia.org/wiki/Anscombe%27s_quartet).<jupyter_code>import matplotlib.pyplot as plt
import pandas as pd
#увеличим дефолтный размер графиков
from pylab import rcParams

rcParams['figure.figsize'] = 13,6<jupyter_output><empty_output><jupyter_text>Matplotlib<jupyter_code>plt.plot(5, 5, 'x')
plt.xlabel('Подпись оси')
# plt.show()
plt.plot([1, 4, 9, 12, 15, 20, 25])
plt.show()
plt.plot([25, 20, 15, 12, 9, 4, 2])<jupyter_output><empty_output><jupyter_text>Поработаем с данными о продажах и оценках видео-игр с [Kaggle Datasets](https://www.kaggle.com/ashaheedq/video-games-sales-2019?select=vgsales-12-4-2019.csv).<jupyter_code>df = pd.read_csv('../data/vgsales-12-4-2019.csv')
print(df.shape)
df.info()
# что видим?
# переведем для порядка годы к integer
df['Year'] = df.Year.astype('Int64')
df.describe()
df.head()<jupyter_output><empty_output><jupyter_text>График– один из наиболее часто используемых типов визуализаций. Отлично подходит, если:- набор данных непрерывен;- количество значений больше 20;- необходимо выявить тенденцию.Построим график по динамике количества вышедших игр<jupyter_code>dynamics_by_region = df[[x for x in df.columns if 'Sales' in x] + ['Year']] \
    .groupby('Year').sum()
dynamics_by_region
# применяем функцию plot из matplotlib
# для каждой дополнительной настройки есть своя функция
plt.plot(dynamics_by_region.index, dynamics_by_region.Global_Sales)
plt.title('Динамика продаж видеоигр')
plt.xlabel('Год')
plt.ylabel('Продажи, млн.')
# можем использовать цикл, чтобы построить графики для каждого региона
for region in [x for x in df.columns if 'Sales' in x]:
    plt.plot(dynamics_by_region.index, dynamics_by_region[region])
    plt.title('Динамика продаж видеоигр')
    plt.xlabel('Год')
    plt.ylabel('Продажи, млн.') 
    plt.legend(dynamics_by_region)<jupyter_output><empty_output><jupyter_text>Метод .plot() в pandas основан на matplotlib. Если мы работаем с датафреймами, то это, как правило, более удобный вариант, чем использование matplotlib самой по себе. Мы сконцентрируемся на этом варианте.Документация: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.htmlАргумент kind, позволяет задать тип графика. Исчерпывающий список типов визуализации:- bar – столбчатая диаграмма;- barh – горизонтальная столбчатая диаграмма;- hist – гистограмма;- box – “ящик с усами”;- kde – ядерная оценка плотности;- area – диаграмма с областями накопления;- pie – круговая диаграмма- scatter – точечная диаграмма;- hexbin – гексагональная диаграмма.<jupyter_code># если работает с табличными структурами, то можем воспользоваться функционалом, 
# встроенным в pandas. Так удобнее
# Метод plot по-умолчанию использует индекс датафрейма для оси Y
# метод plot по-умолчанию строит график
ax = dynamics_by_region['Global_Sales'].plot(title='Динамика продаж видеоигр')
ax.set_xlabel('Год') 
ax.set_ylabel('Продажи, млн.')
# plot без цикла построит графики для каждого региона (столбца)
# если у plot нету нужных методов, то можно применить функции matplotlib
ax = dynamics_by_region.plot(title='Динамика продаж видеоигр') 
ax.set_xlabel('Год') 
ax.set_ylabel('Продажи, млн.')
ax.text(2007, 580, 'Почему отсюда начался спад?')  
ax.legend(loc='upper left');<jupyter_output><empty_output><jupyter_text>Area chartаналогична графику, но пространство между осью Х и линией графика заполняется цветом или рисунком. Лучше всего подходит для отображения изменений в составе комплексной величины с течением времени. Если категорий больше 3-5, то ее использование вряд ли будет оправдано.<jupyter_code># по-умолчанию  Area chart всегда накопительный
ax = dynamics_by_region.plot(kind='area',
                             stacked=False,
                             title='Динамика продаж видеоигр')
ax.set_xlabel('Год') 
ax.set_ylabel('Продажи, млн.')<jupyter_output><empty_output><jupyter_text>Гистограммыиспользуется в статистике для представления распределения величины. По горизонтальной оси откладывается диапазон наблюдаемых значений, разбитый на определенное число (обычно 10-15) интервалов, а по вертикальной – вероятность или частота ее попадания в каждый интервал. По форме гистограммы аналитик может оценить, какому статистическому закону распределения подчиняется величина.<jupyter_code># распределение оценок пользователей
df.User_Score.plot(kind='hist', 
                   bins=15,
                   title='User Score distribution',
#                    xlabel='USer score',
#                    ylabel='Games',
                                        alpha = 0.5,
                   density=True,
                   xticks=range(1, 11))

# # распределение оценок критиков
df.Critic_Score.plot(kind='hist', 
                     bins=10,
                     title='Critic Score distribution',
#                      xlabel='Critic score',
#                      ylabel='Games',
                     alpha = 0.5,
                     density = True,                     
                     xticks=range(1, 11))
# распределение оценок критиков
df.Critic_Score.plot(kind='hist', 
                     bins=10,
                     title='Critic Score distribution',
                     xlabel='Critic score',
                     ylabel='Games',
                     xticks=range(1, 11))<jupyter_output><empty_output><jupyter_text>Столбчатая диаграммаидеально подходит для сравнения показателей. Горизонтальные столбчатые диаграммы обычно используют, когда нужно сравнить показатели между собой. А вертикальные вариант хорошо подходит для демонстрации изменения показателя в разные периоды.<jupyter_code># количество игр в разрезе платформ
games_by_platforms = df[['Name', 'Platform']].groupby('Platform').count()
games_by_platforms
games_by_platforms.loc[['PC', 'X360', 'PS3', 'PS4', 'XOne']].plot(kind='bar', 
                                                                  title='Platforms by Global Sales',
#                                                                   xlabel='Critic score',
#                                                                   ylabel='Global Sales'
                                                                 )
# топ-5 жанров по продажам
top5_genres = df[['Global_Sales', 'Genre']].groupby(by='Genre').sum().sort_values(by='Global_Sales', ascending=False).head(5)
ax = top5_genres.plot(kind='bar')
for i, val in enumerate(top5_genres.values):
    plt.text(i, val, int(val), horizontalalignment='center', verticalalignment='bottom', fontdict={'size':14})
# динамика продаж в разрезе регионов. Выглядит фигово
dynamics_by_region.plot(kind='bar')
# Сделаем с накоплением!
dynamics_by_region.drop('Global_Sales', axis=1).plot(kind='bar', stacked=True)<jupyter_output><empty_output><jupyter_text>Круговая диаграмма[~~худшая диаграмма на свете~~](https://habr.com/ru/company/otus/blog/424647/)  распространенный способ показать структуру набора данных (какую часть от общего количества составляют отдельные значения).  Круговые диаграммы не предназначены для сравнения отдельных категорий друг с другом.По возможности избегайте их. Мы хорошо воспринимаем длины и размеры, но углы и площади нам воспринимать и сравнивать тяжело.<jupyter_code># количество игр по платформам
pie_data = df.Platform.value_counts().sort_values(ascending = False).head(10)
ax = pie_data.plot(kind='pie',
                   title='Quantity of games by platforms')
# количество игр по платформам (берем только топ-5)
top_platforms = df.Platform.value_counts().sort_values(ascending = False).head(5)
ax = top_platforms.plot(kind='pie')
ax.legend()<jupyter_output><empty_output><jupyter_text>Boxplotиспользуется в описательной статистике, компактно изображает распределение величин. Одна из немногих визуализаций, позволяющая показать выбросы.<jupyter_code># очень хорошо подходит для поиска выбросов!
df.User_Score.plot(kind='box',
                   title='User Score distribution')
df[['User_Score', 'Critic_Score']].plot(kind='box',
                                        title='Score distributionn')<jupyter_output><empty_output><jupyter_text>Точечная диаграммаКаждому наблюдению соответствует точка, координаты которой равны значениям двух параметров этого наблюдения. Используются для изучения взаимосвязи между двумя переменными. Также помогают выявлять выбросы.<jupyter_code># посмотрим на взимосвязь оценок и продаж
df.plot(kind='scatter', 
        x='User_Score', 
        y='Global_Sales', 
        title='Correlation between Global Sales and User Score')
plt.show()
df.plot(kind='scatter', 
        x='Critic_Score', 
        y='Global_Sales', 
        title='Correlation between Global Sales and Critic Score')
# добавим третью ось
df.plot(kind='scatter', 
        x='User_Score', 
        y='Critic_Score', 
        s=df.Global_Sales*80,
        title='Correlation between Global Sales and User Score',
       )<jupyter_output><empty_output><jupyter_text>Стилизация таблицКогда построение визуализации неоправданно, можно стилизовать табличную структуру при помощи встроенных инструментов pandas, добавив нужные акценты для лучшего ее восприятия.Документация: https://pandas.pydata.org/pandas-docs/stable/user_guide/style.html<jupyter_code># выведем информацию о топ-10 издателях по продажам
top_developers_df = df.groupby('Developer')[['Global_Sales']].sum()\
    .sort_values('Global_Sales', ascending=False).head(10)
    
top_developers_df
top_developers_df.style.bar(align='mid')<jupyter_output><empty_output><jupyter_text>Seaborn   Seaborn – популярная библиотека готовых шаблонов для статистической визуализации, написанная на основе matplotlib.Имеет выразительный высокоуровневый интерфейс (построение большинства простых графиков происходит в одну строчку кода), а встроенные в нее стили более приятны.Импорт: import seaborn as sns (библиотека названа в честь Сэмюела Нормана Сиборна (S.N.S) – героя сериала The West Wing, который очень любил автор библиотеки).Документация: https://seaborn.pydata.org/tutorial.html<jupyter_code>import seaborn as sns
# посмотрим зависимость продаж и оценок критиков
ax = sns.regplot(data=df, x='Critic_Score', y='Global_Sales', color='green', marker='+')
ax.set_title('Correlation between Global Sales and Critic Scores')<jupyter_output><empty_output><jupyter_text>C помощью `seaborn` можно построить достаточно сложные визуализации, которые были бы очень сложны для представления в коде при использовании `matplotlib`. Рассмотрим часть из них. Посмотрим на **распределение оценок критиков `Critic_Score`**. Для этого построим __`distplot`__. По-умолчанию на визуализации отображается гистограмма и [kernel density estimation](https://en.wikipedia.org/wiki/Kernel_density_estimation).<jupyter_code>ax = sns.distplot(df.Critic_Score)
ax.set_title('Critic Score distribution')<jupyter_output><empty_output><jupyter_text>Для того чтобы подробнее посмотреть на взаимосвязь двух численных признаков можно использовать __`joint_plot`__ – это гибрид `scatter plot` и `histogram`. Посмотрим на то, как связаны между собой **оценка критиков `Critic_Score` и оценка пользователя `User_Score`**.<jupyter_code>sns.jointplot(x='Critic_Score', y='User_Score', 
              data=df, kind='reg')<jupyter_output><empty_output><jupyter_text>**pair plot (scatter plot matrix)** поможет нам посмотреть на одной картинке, как связаны между собой различные признаки в наборе данных<jupyter_code>sns.pairplot(df[['Global_Sales', 'Critic_Score', 'User_Score']])<jupyter_output><empty_output><jupyter_text>Давайте **сравним оценки критиков игр для топ-5 крупнейших игровых платформ** при помощи `boxplot`.<jupyter_code>top_platforms = df.Platform.value_counts().sort_values(ascending = False).head(10).index.values
top_platforms
sns.boxplot(x="Platform", y="Critic_Score", 
            data=df[df.Platform.isin(top_platforms)])<jupyter_output><empty_output><jupyter_text>`Heat map` позволяет посмотреть на распределение какого-то численного признака по двум категориальным. Визуализируем **суммарные продажи игр по жанрам и игровым платформам**.<jupyter_code>platform_genre_sales = df[df.Platform.isin(top_platforms)].pivot_table(
                        index='Platform', 
                        columns='Genre', 
                        values='Global_Sales', 
                        aggfunc=sum).fillna(0)

platform_genre_sales
sns.heatmap(platform_genre_sales)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09926470588235294, 'fraction_numerical': 0.009650735294117647, 'mean_word_length': 4.292663153627888, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 75, 'https://': 8, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 11, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '18', 'dir': 'jupyter-structured-clean-dedup', 'id': '423067', 'license': 'Apache-2.0', 'n_tokens_mistral': 4942, 'n_tokens_neox': 5377, 'n_words': 1014, 'path': 'module_3/Module_suppl_notebooks/viz.ipynb', 'repo_name': 'EugeniaVoytik/Skillfactory_Data_Science_Degree', 'size': '13071'}