DevGang
Авторизоваться

Как создавать быстрые и точные диаграммы разброса с большим количеством данных на Python 

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

В чем проблема matplotlib? Что ж, matplotlib это отличная библиотека Python, и она определенно обязательна для изучения данных. Но matplotlib это также огромный универсал и может работать неоптимально в некоторых сценариях. Это один из тех.

Давайте предположим, что мы имеем массив X и его форма (1_000_000, 2). Каждый столбец представляет одну ось. Итак, любая строка - это координата

import matplotlib.pylot as plt
plt.scatter(X[:, 0], X[:, 1])
plt.show()
График разброса с использованием matplotlib.&nbsp;Время работы, вкл.&nbsp;экономия: 6.4с.<br>
График разброса с использованием matplotlib. Время работы, вкл. экономия: 6.4с.

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

import matplotlib.pylot as plt
plt.scatter(X[:, 0], X[:, 1], s=1, alpha=0.1)
plt.show()

Может datashader?

datashader - отличная библиотека для визуализации больших наборов данных. Основное улучшение связано с процессом растеризации: в matplotlib будет создан круг для каждой точки данных, а затем, когда вы отображаете свои данные, он должен будет выяснить, какие пиксели на вашем холсте занимает каждая точка. Обычно каждая точка занимает несколько пикселей. datashader вместо этого вы разделите ваше 2D-пространство на горизонтальные width и вертикальные height интервалы. А затем он просто проверяет, какую ячейку занимает каждый образец. Если этот процесс кажется вам знакомым, то это потому, что именно так вы создаете гистограмму. В этом случае 2D-гистограмма с интервалами одинаковой ширины. Гистограмма, которую вы создали, уже имеет ту же форму, что и ваше изображение. Итак, все, что осталось, это применить цветовую карту. Мне очень нравится fire из библиотеки colorcet. Обратите внимание, что datashader только принимает в качестве входных данных DataFrame (будь то pandasdask или другие) и ваши данные должны быть сохранены как float32.

Нам нужны дополнительные пакеты:

pip install datashader, colorcet, pandas
import datashader as ds
import pandas as pd
import colorcet as cc
import matplotlib.pyplot as plt

df = pd.DataFrame(data=X, columns=["x", "y"])  # create a DF from array
cvs = ds.Canvas(plot_width=500, plot_height=500)  # auto range or provide the `bounds` argument
agg = cvs.points(df, 'x', 'y')  # this is the histogram
img = ds.tf.set_background(ds.tf.shade(agg, how="log", cmap=cc.fire), "black").to_pil()  # create a rasterized image
plt.imshow(img)
plt.axis('off')
plt.show()
График разброса, созданный с помощью datashader.&nbsp;Время работы, вкл.&nbsp;экономия: 0.69с.<br>
График разброса, созданный с помощью datashader. Время работы, вкл. экономия: 0.69с.

Точки больше не могут частично перекрываться, и, поскольку вы создаете гистограмму, палитра решит вашу предыдущую проблему непрозрачности. Вы можете решить, как вы хотите нормализовать данные (используя параметр how). Здесь мы устанавливаем его как логарифмический, но обычно я бы рекомендовал оставить его по умолчанию, который использует более сложный метод.

А теперь давайте просто добавим на график цветовую полосу. Фу! Как? Все, что у нас есть, это гистограмма и растровое изображение. Мы можем отображать изображение matplotlib, но не имеем информации о цветовой карте. Вероятно, есть какой-то хак, но давайте будем честными: это будет не что иное, как грязный хак и может внести много путаницы. Таким образом datashader, это замечательно, быстро и просто в использовании, но за это приходится платить: никаких цветных полос и интерактивных графиков (т.е. нет графического интерфейса, который позволяет масштабировать, вращать и т.д.). Тем не менее, он действительно хорош при создании внешней графики. Итак, попробуйте! Особенно, когда вы имеете дело с данными геолокации.

Еще более быстрое решение… и цветные полосы!

Для меня динамические графики не так важны, но цветные полосы мне очень нужны. Итак, я пошел дальше и разработал свое собственное решение. На самом деле это действительно просто. Первоначально я использовал numpy для вычисления 2D-гистограммы, а затем с помощью matplotlib обрабатывать затенение. Но numpy.histogram2d работает довольно медленно, поэтому я перешел на fast_histogram. Я снова использую карту colorcet.fire, но получаю к ней доступ через cc.cm, чтобы быть совместимым с matplotlib. Кроме того, я предлагаю аргумент norm в пользу использования логарифмической палитры. Имейте в виду vmin=0, что это недопустимо, потому что логарифм нуля не определен. Вот почему все значения 0 сопоставляются с так называемым bad цветом. Поэтому просто установите bad цвет на наименьшее значение (или на любой другой цвет, который вы хотите, чтобы был ваш фон).

Нам нужны дополнительные пакеты:

pip install fast-histogram colorcet
import colorcet as cc
import matplotlib.colors as colors
import matplotlib.pyplot as plt
from fast_histogram import histogram2d
cmap = cc.cm["fire"].copy()
cmap.set_bad(cmap.get_under())  # set the color for 0
bounds = [[X[:, 0].min(), X[:, 0].max()], [X[:, 1].min(), X[:, 1].max()]]
h = histogram2d(X[:, 0], X[:, 1], range=bounds, bins=500)
plt.imshow(h, norm=colors.LogNorm(vmin=1, vmax=h.max()), cmap=cmap)
plt.axis('off')
plt.show()

Обратите внимание, что созданные диаграммы разброса повернуты из-за способа вывода данных fast_histogram.

Чтобы показать цветовую полосу, просто добавьте plt.colorbar() раньше plt.show().

Точечная диаграмма, созданная с помощью fast_histogram, пользовательского затенения и цветовой полосы!<br>
Точечная диаграмма, созданная с помощью fast_histogram, пользовательского затенения и цветовой полосы!

Источник:

#Python #Matplotlib #Numpy
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

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

Попробовать

В подарок 100$ на счет при регистрации

Получить