Лучшие способы увидеть вклад отдельных лиц в единое целое и их изменения с течением времени при различных размерах наборов данных (включая простые визуальные демонстрации, код и данные)

Построение пропорций целого может быть одной из самых распространенных задач визуализации данных. Примеры включают региональные различия в уровне счастья, экономических показателях или преступности, демографические различия в структуре голосования, доходах или расходах, или вклад отдельных частей бизнеса в его чистую прибыль. Часто данные также описывают изменения во времени, которые могут составлять месяцы, кварталы, годы или десятилетия.

Несмотря на то, что все они относятся к пропорциям целого, часто не существует универсального подхода, который подошел бы для всех.

В этой статье я описываю то, что я считаю эффективными методами передачи пропорций целого, а также их изменение с течением времени. Я также буду исследовать изменения в эффективности диаграмм по мере изменения количества точек данных или рядов.

Как всегда, эта статья также будет включать примеры, чтобы вы могли следить за ними и создавать свои собственные интересные визуализации данных.

В качестве кода я собираюсь использовать знаменитый набор данных Gapminder и некоторые данные о доле бросков в баскетболе Toronto Raptors в прошлом сезоне. Это просто примеры наборов данных, показывающих пропорции, поэтому вам не нужно ничего знать об экономике или баскетболе, чтобы следить за ними!

Прежде чем мы начнем

Данные

Я включаю код и данные в свое репозиторий GitLab здесь (каталог viz_proportions). Так что, пожалуйста, не стесняйтесь играть с ним / улучшать его.

Пакеты

Полагаю, вы знакомы с питоном. Тем не менее, даже если вы относительно новичок, это руководство не должно быть слишком сложным.

Вам понадобятся pandas и plotly. Установите каждый (в виртуальной среде) с помощью простого pip install [PACKAGE_NAME].

Визуализация простых пропорций

Загрузить и проверить данные

Удобно, что пакет plotly предоставляет нам несколько игрушечных наборов данных, с которыми мы можем поиграть, и Набор данных Gapminder является одним из них. Мы можем загрузить его с помощью:

import plotly.express as px
gap_df = px.data.gapminder()

Изучите данные с помощью gap_df.info() и gap_df.head(), и мы увидим, что они показывают данные для нескольких стран за каждый год.

Он включает численность населения и ВВП на душу населения, поэтому давайте умножим эти два, чтобы получить данные о ВВП.

gap_df = gap_df.assign(gdp=gap_df['pop'] * gap_df['gdpPercap'])

Визуализация только данных за один год

Для самых первых визуализаций давайте сравним несколько разных типов диаграмм. Исходные данные включают данные 1952 года по 142 странам. Давайте упростим сбор данных по континентам и только за последний год в cont_df.

year_df = gap_df[gap_df.year == max(gap_df.year)]
cont_df = year_df.groupby('continent').agg({'gdp': 'sum'})
cont_df.reset_index(inplace=True)

Здесь фрейм данных сгруппирован по континентам и сбрасывает индекс, потому что в Plotly Express легче работать с «плоским» фреймом данных.

Теперь данные можно построить с помощью Plotly Express. Код для построения этих основных графиков очень прост. Замечу, что для пузырьковой диаграммы я добавляю произвольную переменную с именем dataType, просто чтобы ее можно было использовать для выравнивания пузырьков в направлении Y.

# Pie chart
fig = px.pie(cont_df, values='gdp', names='continent')
fig.show()
# Bar chart
fig = px.bar(cont_df, color='continent', x='continent', y='gdp')
fig.show()
# Horizontal bar chart - stacked
fig = px.bar(cont_df, color='continent', x='gdp', orientation='h')
fig.show()
# Bubble chart
fig = px.scatter(cont_df.assign(dataType='GDP'), color='continent', x='continent', y='dataType', size='gdp', size_max=50)
fig.show()

Я собрал здесь результаты:

Все диаграммы, за исключением столбчатых диаграмм, не подходят для обозначения сравнительных размеров.

Когда точки данных близки по размеру, как данные ВВП для Азии, Америки, Европы, гистограммы с накоплением и круговые диаграммы не позволяют легко сравнивать точки данных, поскольку они начинаются с разных источников.

Круговые диаграммы также проблематичны в том смысле, что различия в углах, как известно, трудно точно уловить, поэтому мы просто проигнорируем их в будущем.

Пузырьковые диаграммы работают немного лучше, но поскольку размер пузыря зависит от размера набора данных, различия в радиусах становятся меньше, чем у столбчатых диаграмм (на квадратный корень).

Что происходит, когда мы добавляем измерение времени?

Визуализация данных с течением времени

Для этой части нам понадобится фреймворк с данными за несколько лет. Мы могли бы использовать весь набор данных, но давайте все же будем простыми, с данными за небольшое количество лет.

Набор данных содержит несколько лет, но не каждый год. Мы можем использовать gap_df.year.unique(), чтобы узнать, за какие годы доступны данные, и выбрать годы после 1985 года, то есть пять разных лет.

Наш сводный фрейм данных может быть построен следующим образом:

mul_yrs_df = gap_df[gap_df.year > 1985]
mul_yr_cont_df = mul_yrs_df.groupby(['continent', 'year']).agg({'gdp': 'sum'})
mul_yr_cont_df.reset_index(inplace=True)

Метод groupby создаст мультииндексный фрейм данных, который лучше всего рассматривать как вложенный индекс (continent, year) (если вы хотите узнать больше об иерархическом / мультииндексном, это отличный ресурс). Затем индекс снова выравнивается, прежде чем мы построим их.

# Bar chart
mul_yr_cont_df = mul_yr_cont_df.assign(yrstr=mul_yr_cont_df.year.astype(str))
fig = px.bar(mul_yr_cont_df, color='continent', y='gdp', x='yrstr', barmode='group')
fig.show()
# Horizontal bar chart - stacked
fig = px.bar(mul_yr_cont_df, color='continent', x='gdp', orientation='h', y='yrstr')
fig.show()
# Bubble chart
fig = px.scatter(mul_yr_cont_df, y='continent', x='yrstr', color='continent', size='gdp', size_max=50)
fig.show()

При этом сохраняются предыдущие свойства в отношении легкости, с которой относительные пропорции можно увидеть на гистограммах. Но можно сделать новые наблюдения, добавив к данным еще одно измерение.

Сложенная полоса дает возможность продемонстрировать изменения размера по отношению к общему размеру выборки, хотя размеры каждой серии по-прежнему очень трудно сравнивать.

Что касается сгруппированных гистограмм, группировка по оси x становится важной, поскольку сравнения между разными группами становятся более сложными, в то время как внутри одной группы остается легко. Попробуйте построить и сравнить эти два:

fig = px.bar(mul_yr_cont_df, color='continent', y='gdp', x='yrstr', barmode='group')
fig.show()
fig = px.bar(mul_yr_cont_df, color='yrstr', y='gdp', x='continent', barmode='group')
fig.show()

На верхнем рисунке сравнения по годам имеют приоритет в ущерб сравнениям по континентам, и наоборот, на нижнем рисунке.

Для сравнения по обеим осям пузырьковая диаграмма размещает данные в сетке, что упрощает сравнение изменений по обоим измерениям.

Если изменения размера в пузырьковых диаграммах недостаточно заметны, возможно, лучше подойдут гистограммы с сеткой (подзаголовки):

fig = px.bar(mul_yr_cont_df, color='continent', facet_col='continent', x='gdp', orientation='h', facet_row='yrstr')
fig.update_yaxes(showticklabels=False)
fig.show()

Замечательно. Но часто на каждой оси имеется более 5 точек данных. Итак, что будет, если количество серий увеличится?

Визуализация больших наборов данных

Давайте повторим графики для всех данных за 12 лет набора данных (код здесь не показан для краткости - см. Репозиторий git).

Здесь мы уже можем начать видеть некоторые ограничения пространства с сгруппированными гистограммами. Сравнения между различными группами также становятся более трудными, поскольку отдельные столбцы теряются в лесу высоких цветных полос, а относительные изменения в соседних столбцах играют шутку с нашим разумом.

Хотя этот набор данных визуально относительно хорошо масштабируется с размером, чему способствует рост ВВП со временем, ограничения легко увидеть.

В качестве последнего момента давайте взглянем на более крупный набор данных, который менее упорядочен.

Бонусные сюжеты: доля ударов по баскетболу (Toronto Raptors 2019)

В течение сезона НБА, продолжительностью 82 48 минут, команда выполняет около 7000 бросков. В случае с Toronto Raptors у них было 14 игроков, сделавших не менее 1% этих выстрелов. Итоговые 15 «игроков» (14 + 1 «другие») показаны ниже, разделенные на каждые 2-минутные сегменты.

Этот набор данных также немного отличается от приведенного выше, поскольку я покажу процентное распределение.

Как они выглядят в каждом из вышеперечисленных типов сюжетов?

По мере увеличения количества точек данных в обоих измерениях и увеличения отношения максимального к минимальному размерам пузырьковая диаграмма в сетке становится самостоятельной.

На пузырьковой диаграмме то, что было бы изменением высоты от 1 до 25 на гистограмме, становится изменением радиуса от 1 до 5. Тот факт, что изменение размера преобразуется в изменение радиуса, в действительности сжимает визуальное несоответствие и помогает отображать большие диапазоны. Он (наряду с подходом на основе столбиков) также имеет дополнительное преимущество, заключающееся в возможности продемонстрировать четвертую переменную в виде цвета, поскольку пространственное положение определяет ее два измерения.

Как вы могли догадаться, я предпочитаю этот тип подзаголовка, поскольку размеры набора данных становятся больше, особенно когда набор данных становится больше. Но, как вы видели ранее, в других ситуациях другие типы визуализации работают намного лучше.

Итак - что выбрать?

Вы могли предвидеть это, но, на мой взгляд, универсального подхода не существует. И я даже не начал царапать поверхность этой области в визуализации пропорций - масштабирования, различных подходов к использованию цветов, типов символов, использования общих форм распределения и выделения пропорций и т. Д.

Но я надеюсь, что эти примеры были, по крайней мере, полезны для вас при просмотре различных типов визуализаций и о том, как их эффективность может измениться в зависимости от размера выборки. Я считаю, что нет ничего лучше практики, чтобы по-настоящему изучить визуализацию данных и стать лучше. Так что выберите набор данных и действуйте - чем лучше вы знакомы с предметной областью, тем лучше.

Если вам понравилось, скажите 👋 / подписывайтесь на twitter или следите за обновлениями. Я также написал эту статью о моих любимых книгах по визуализации данных, если вы не читали ее раньше:



Кроме того, это был фаворит публики:



Увидимся в следующий раз!