Создание тепловой карты в MatPlotLib с использованием набора данных разброса

StackOverflow https://stackoverflow.com/questions/2369492

Вопрос

У меня есть набор точек данных X, Y (около 10 тыс.), которые легко построить как диаграмму рассеяния, но которые я хотел бы представить как тепловую карту.

Я просмотрел примеры в MatPlotLib, и все они, кажется, уже начинаются со значений ячеек тепловой карты для создания изображения.

Есть ли метод, который преобразует набор x, y, все разные, в тепловую карту (где зоны с более высокой частотой x, y будут «теплее»)?

Это было полезно?

Решение

Если вам не нужны шестиугольники, вы можете использовать функцию numpy histogram2d:

родовое слово

Таким образом получается тепловая карта 50 x 50.Если вы хотите, скажем, 512x384, вы можете поместить bins=(512, 384) в вызов histogram2d.

Пример: Пример тепловой карты Matplotlib

Другие советы

В лексиконе Matplotlib я думаю, вам нужен график hexbin .

Если вы не знакомы с этим типом графика, это просто двумерная гистограмма , в которой плоскость xy разбита на мозаику с помощью правильной сетки из шестиугольников.

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

Хотя шестиугольники используются реже, чем, например, круги или квадраты, они являются лучшим выбором для геометрии контейнера биннинга:

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

  • шестиугольник - это наивысший n-многоугольник, который дает правильную плоскость. тесселяция (т. е. вы можете смоделировать пол на кухне с помощью плиток шестиугольной формы, потому что у вас не будет пустого пространства между плитками, когда вы закончите - это не верно для всех других значений с более высокими n, n >= 7, полигоны).

( Matplotlib использует термин hexbin plot; так (AFAIK) все библиотеки графиков для R ; все же я не Не знаю, является ли это общепринятым термином для графиков этого типа, хотя я подозреваю, что это вероятно, учитывая, что hexbin - это сокращение от гексагонального разбиения , которое описывает важный шаг при подготовке данных к отображению.)


родовое слово

введите описание изображения здесь

Вместо использования np.hist2d, который обычно создает довольно уродливые гистограммы, я хотел бы переработать py-sphviewer , пакет Python для рендеринга моделирования частиц с использованием ядра адаптивного сглаживания, который можно легко установить из pip (см. документацию на веб-странице). Рассмотрим следующий код, основанный на примере:

родовое слово

в результате получается следующее изображение:

введите здесь описание изображения

Как видите, изображения выглядят довольно красиво, и мы можем идентифицировать на них различные подструктуры. Эти изображения создаются с распределением заданного веса для каждой точки в определенной области, определяемой длиной сглаживания, которая, в свою очередь, определяется расстоянием до ближайшего соседа nb (я выбрал 16, 32 и 64 для примеров). Таким образом, области с более высокой плотностью обычно распределяются по более мелким областям по сравнению с областями с более низкой плотностью.

Функция myplot - это очень простая функция, которую я написал для того, чтобы передать данные x, y в py-sphviewer, чтобы он творил чудеса.

Если вы используете 1.2.x

родовое слово

gaussian_2d_heat_map

Изменить: для лучшего приближения к ответу Алехандро см. ниже.

Я знаю, что это старый вопрос, но хотел добавить кое-что к ответу Алехандро: если вам нужно красивое сглаженное изображение без использования py-sphviewer, вы можете вместо этого использовать np.histogram2d и применить фильтр Гаусса (из scipy.ndimage.filters) к тепловой карте:

родовое слово

Производит:

 Выходные изображения

Диаграмма рассеяния и s= 16, нанесенные поверх друг друга для Агапе Гальо (щелкните для лучшего обзора):

 поверх друг друга


Одно отличие, которое я заметил в моем подходе к гауссовскому фильтру и подходу Алехандро, заключалось в том, что его метод показывает локальные структуры намного лучше, чем мой. Поэтому я реализовал простой метод ближайшего соседа на уровне пикселей. Этот метод вычисляет для каждого пикселя обратную сумму расстояний до ближайших точек кода кодового тега в данных. Этот метод с высоким разрешением довольно затратен с точки зрения вычислений, и я думаю, что есть более быстрый способ, поэтому дайте мне знать, если у вас есть какие-либо улучшения. Во всяком случае, вот код:

родовое слово

Результат:

 Сглаживание ближайшего соседа

У Seaborn теперь есть функция Jointplot , которая здесь должна хорошо работать:

родовое слово

 демонстрационное изображение

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

родовое слово

Итак, у меня есть набор данных с Z-результатами для координат X и Y. Однако я вычислял несколько точек за пределами интересующей области (большие промежутки) и множество точек в небольшой интересующей области.

Да, здесь становится сложнее, но и веселее. Некоторые библиотеки (извините):

родовое слово

Pyplot - это мой графический движок сегодня, cm - это набор цветных карт с интересным выбором. numpy для расчетов, и griddata для привязки значений к фиксированной сетке.

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

родовое слово

Итак, мы определили сетку с 500 пикселями между минимальным и максимальным значениями x и y.

По моим данным, в наиболее интересной области доступно намного больше 500 значений; тогда как в области с низким процентом в общей сетке нет даже 200 значений; Между графическими границами x_min и x_max еще меньше.

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

Сейчас я определяю свою сетку. Для каждой пары xx-yy я хочу иметь цвет.

родовое слово

Почему странная форма? scipy.griddata хочет форма (n, D).

Griddata рассчитывает одно значение для каждой точки в сетке заранее определенным методом. Выбираю «ближайший» - пустые точки сетки будут заполнены значениями от ближайшего соседа. Это выглядит так, как будто области с меньшим количеством информации имеют более крупные ячейки (даже если это не так). Можно выбрать «линейную» интерполяцию, тогда области с меньшим количеством информации будут выглядеть менее резкими. Дело вкуса, правда.

родовое слово

И мы передаем команду matplotlib для отображения графика

родовое слово

Вокруг заостренной части V-образной формы, как видите, я проделал много вычислений во время поиска золотого пятна, тогда как менее интересные части почти везде имеют более низкое разрешение.

 Тепловая карта SVC в высоком разрешении

Создайте двумерный массив, который соответствует ячейкам на вашем окончательном изображении, назовите, скажем, heatmap_cells, и создайте его как все нули.

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

Для каждой необработанной точки данных с общим кодом кода и кодом кода:

x_value

Очень похоже на ответ @ Piti , но для генерации баллов используется 1 вызов вместо 2:

родовое слово

Вывод:

 2d_gaussian_heatmap

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

родовое слово

Вот результат введите описание изображения здесь

 введите описание изображения здесь

Вот один, который я сделал на наборе в 1 миллион точек с 3 категориями (красный, зеленый и синий).Вот ссылка на репозиторий, если вы хотите попробовать эту функцию. Github Repo

родовое слово
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top