# Графики в Python ## Matplotlib [Matplotlib](https://matplotlib.org/) -- классика, де-факто стандарт визуализации в Python. Плюсы: + Гигантское количество примеров и туториалов, знают все адепты Data Science в мире Python. + Можно сделать что угодно, хоть енотов рисовать. Минусы: + Очень некрасивые графики по умолчанию, надо патчить или настраивать. + Сложно. Приходится писать много кода, всякие циклы, самому конвертировать данные, постоянно лезть в документацию. + Тяжело читать код. + всё рисуется через глобальный объект plot, который упрощает работу с ядром библиотеки. Сядром напрямую никто не работает, там уж совсем черная магия. Как результат, сложно работать с несколькими графиками одновременно, совмещать графики и всё такое. ## Seaborn [Seaborn](https://seaborn.pydata.org/) -- стандарт номер два, сразу за matplotlib. Собственно, представляет из себя как раз обертку над matplotlib с модным дизайном и функциями для рисования самых нужных графиков. Плюсы: + Красиво. + Просто. Всего-то надо передать данные в одну функцию, а она уже всё сделает. + Может в Pandas. + Опять-таки, много документации и хорошо знаком адептам Data Science. Минусы: + Сложно что-то кастомизировать, часто приходится патчить seaborn графики через matplotlib. Например, для наложения нескольких графиков друг на друга. + Иногда надо самому размечать данные. Например, [генерировать палитру для heatmap](https://seaborn.pydata.org/examples/structured_heatmap.html). ## Altair [Altair](https://github.com/altair-viz/altair) -- штука не столь известная, но очень хорошая. Плюсы: + Максимально просто! Серьезно, проще некуда. Передаем pandas DataFrame, указываем тип графика, указываем какие колонки использовать как x, y, fill, color, shape и т.д., и всё! + В принципе, неплохо конфигурируется. + Красивый. Не такой, как seaborn, но всё же. + Графики интерактивные, с возможностью экспорта. Минусы: + Нет некоторых вещей. Например, ящик с усами там рисуется по кускам (отдельно ящик, отдельно каждый ус), что довольно муторно, причём без игнорирования выбросов (что очень нужно, на самом деле). + Что-то сложно сконфигурировать. Например, я не нашёл, как там нормально поменять подписи к fill. ## Ggplot2 [ggpy](https://github.com/yhat/ggpy) -- порт ggplot2 из R. Ggplot2 реализует удобную грамматику графиков. Основная идея в том, что график состоит из разных слоев. Чем сложнее график, тем больше слоев надо. Сначала идет сетка, потом сам график, а может и несколько, затем оси, легенда. Ну и график -- просто сумма таких слоев. Это интуитивно понятно, удобно, просто. Я добавил сюда ggpy, чтобы рассказать вам про ggplot2. Но про плюсы я рассказывать не буду, потому что один минус перекрывает всё: проект больше не поддерживается. Авторы пропали, компанию, которая это делала, поглотили, PR не принимаются. Как следствие, ggpy не совместим с новыми версиями pandas. ## Plotnine [Plotnine](https://github.com/has2k1/plotnine) -- второй проект, копирующий ggplot. Плюсы: + Можно нарисовать что угодно! Даже анимацию. + Код хорошо читается. + Красиво, есть разные стили: seaborn, xkcd и т.д. + Гораздо проще совмещать разные графики, чем в любой из вышеперечисленных библиотек. Минусы: + Документация. Можно сказать, её нет. Есть несколько "туториалов" с решениями редких кейсов, да галерея, которая, опять-таки, рисует всякие бесполезные штуки типа грифа гитары. Круто, но ничем не поможет. Есть только документация к API, и то описаны только параметры, а не сам объект. + Уступает по выразительности оригинальному ggplot2. В частности, функция `factor` в ggplot несравнимо мощнее. Здесь же нельзя для неё задать порядок сортировки, подписи и т.д. В общем, Plotnine мне нравится больше всего, но отсутствие документации увеличивает порог вхождения. ## Show me the code! Давайте посмотрим на выживание пассажиров титаника в зависимости от класса. Всего там три класса. Первый -- элита, третий -- самые дешевые билеты. Сделаем по столбцу на каждый класс, высота будет показывать количество пассажиров, а также разделим столбцы на две части: выжившие и нет. Код на R: ```r ggbar <- ggplot(titanic) + geom_bar(stat = "bin", width=.6) ggbar + aes(x = factor(Pclass), fill = factor(Survived, labels = c("No", "Yes"))) + scale_fill_manual (values=colours[]) + guides(fill=guide_legend(title=NULL)) + ylab(NULL) + xlab("Passager class") ``` Код на plotnine: ```python import pandas as pd import plotnine as gg titanic = pd.read_csv('train.csv') ( gg.ggplot(titanic) + gg.geom_bar( gg.aes( x='factor(Pclass)', fill='factor(Survived)', ), ) + gg.scale_fill_hue( labels=['No', 'Yes'], ) + gg.theme_seaborn() ) ``` Код на altair, только у меня не получилось нормально подписать Survived: ```python alt.Chart(titanic).mark_bar().encode( x='Pclass:N', y='count()', fill='Survived:N', ).properties( width=300, ) ``` ## More! Я тут не рассматривал интерактивные графики, не приводил примеры кода. Так что рекомендую почитать ещё: + [Python Graph Gallery](https://python-graph-gallery.com/all-charts/) -- примеры графиков с кодом, сгенерированных в seaborn и matplotlib. + [The Best Python Data Visualization Libraries](https://www.fusioncharts.com/blog/best-python-data-visualization-libraries/) + [10 Useful Python Data Visualization Libraries](https://mode.com/blog/python-data-visualization-libraries) + [Сравнение кода визуализаций](https://nipunbatra.github.io/blog/2017/50-ggplot-python-1.html). Оригинальное название не привожу, оно вообще нерелевантно содержанию. В это notebook'е приведен код и итоговая визуализация на разных библиотеках, рисующая один и тот же сложный график с точками, линиями, подписями. Отличный способ сравнить код разных библиотек.