-Inf в цветовой карте: низкий уровень в MATLAB, высокий уровень в Python?

Я портировал некоторый код MATLAB на Python, включая утилиту построения графиков, которая отображает цветовую карту некоторых данных в 2D-матрице (списке). Утилиты построения графиков MATLAB и Python очень похожи, поэтому я могу сделать их визуально достаточно близкими, с небольшими усилиями.

Я использую тестовую матрицу:

X = [ 1  0  3 ]
    [ 4  5  6 ]
    [ 7  8  9 ]

MATLAB с тестовой матрицей

X = [1 0 3;
     4 5 6;
     7 8 9];
figure(1);
imagesc(X);
colormap(hot);
colorbar;

Python с тестовой матрицей

import numpy as np
import matplotlib as plt

X = [ [1,0,3] , [4,5,6] , [7,8,9] ]
fig = []
fig.append( plt.figure(1) )
plt.imshow(X, cmap='hot', interpolation='nearest', aspect='auto')
plt.colorbar()
fig[0].show()

Эта проблема возникает, когда я конвертирую в дБ (беру log10 каждого элемента и умножаю на 10), что дает мне тестовую матрицу дБ.

Y = [  0.0000    -Inf        4.7712 ]
    [  6.0206     6.9897     7.7815 ]
    [  8.4510     9.0309     9.5424 ]

MATLAB с тестовой матрицей дБ

Y = 10*log10(X)
figure(2);
imagesc(Y);
colormap(hot);
colorbar;

Python с тестовой матрицей дБ

Y = 10*np.log10(X)
fig.append( plt.figure(2) )
plt.imshow(X, cmap='hot', interpolation='nearest', aspect='auto')
plt.colorbar()
fig[1].show()

Что случилось с верхним средним элементом? Это -Inf, что следует рассматривать как низкое значение. В MATLAB он устанавливается равным наименьшему значению, которое существует в массиве, в данном случае 0. Это имеет смысл, потому что, хотя -Inf меньше 0, это разрушило бы масштабирование, если бы мы использовали его «фактическое значение».

С другой стороны, Python интерпретирует это значение -Inf как высокое значение, устанавливая его равным наивысшему значению в массиве - 9,5424. Для меня это имело бы смысл, если бы значение было просто Inf. Однако это определенно -Inf, как и должно быть. Почему здесь неточность, и могу ли я исправить это, не влияя ни на что другое?

РЕДАКТИРОВАТЬ: Очевидно, я могу заменить all -Inf на Inf, найти минимум матрицы и заменить все Inf на min. Однако я работаю с большими наборами данных, поэтому делать это и сохранять исходные данные нетронутыми не очень эффективно. В идеале должен быть способ изменить способ интерпретации бесконечных значений средством построения графиков.


person Alex Jones    schedule 12.07.2017    source источник
comment
Это похоже на проблему с питоном, не связанную с Matlab. Обе реализации могут свободно реализовывать граничные случаи, как они хотят. Рассмотрите возможность удаления тега Matlab. Я думаю, что ваш ответ уже дает ответ, или вы можете изменить исходный код python.   -  person m7913d    schedule 12.07.2017
comment
Я ищу способ не копировать каждый огромный набор данных, который обрабатывается на сервере, и добавлять ненужное время вычислений для построения графика.   -  person Alex Jones    schedule 12.07.2017
comment
Python отображает его как самый высокий цвет цветовой карты или просто не рисует его, позволяя цвету осей фона просвечивать?   -  person gnovice    schedule 12.07.2017
comment
@gnovice Это вполне может быть так, я не думал об этом ... Если бы это было так, я полагаю, изменение цвета осей исправило бы это, если это возможно.   -  person Alex Jones    schedule 12.07.2017


Ответы (1)


Python не отображает -Inf как самый высокий цвет цветовой карты. Он просто этого не рисует. Вы можете подтвердить это, переключившись на цветовую карту, в которой нет белого цвета, например 'cool':

plt.imshow(Y, cmap='cool', interpolation='nearest', aspect='auto')
plt.show()

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

Python обрабатывает -Inf (а также Inf и NaN) в изображении, не отображая этот патч, оставляя цвет осей видимым сзади. При использовании imagesc MATLAB устанавливает -InfNaN) на самое низкое значение цветовой карты и Inf до максимального значения цветовой карты. При использовании pcolor MATLAB обрабатывает NaN значения, такие как Python, не отображая их .

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

Если вы просто хотите исправить этот конкретный пример (установив для любых не конечных значений черный цвет), вы можете использовать _ 13_ для цветовых карт:

cmap=plt.cm.hot
cmap.set_bad('k')
plt.imshow(Y, cmap=cmap, interpolation='nearest', aspect='auto')
plt.show()

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

person gnovice    schedule 12.07.2017