Нелинейные цветовые карты для трехмерных контурных графиков в matplotlib python

Привет, у меня есть набор данных, которые мне нужно построить в 3D.

Я использовал для этого matplotlibs plot_surface, и, поскольку некоторые из моих данных имеют большое значение, большинство из которых имеют небольшое значение. т.е. наибольшее пиковое значение 0,7 по сравнению с 0,15 в качестве следующего по величине пика. Поэтому мне нужно было использовать какую-то нелинейную цветовую карту, иначе мелкие детали были бы полностью скрыты.

Поэтому я попробовал следующее создание нелинейной цветовой карты source:

class nlcmap(object):
    def __init__(self, cmap, levels):
        self.cmap = cmap #original colourmap
        self.N = cmap.N 
        self.levels = numpy.asarray(levels, dtype='float64') 
        self._x = self.levels       
        self.levmax = self.levels.max() 
        self._y = numpy.linspace(0.0, self.levmax, len(self.levels)) 


    def __call__(self, xi, alpha=1.0, **kw):
        yi = numpy.interp(xi, self._x, self._y) 
        return self.cmap(yi / self.levmax, alpha)

чтобы создать пользовательскую карту цветов для трехмерного контурного графика:

ThreeD_spectrum_figure = matplotlib.pyplot.figure()
ThreeD_spectrum_axis = ThreeD_spectrum_figure.add_subplot(111, projection="3d")

colourmap_levels = [0,0.01,0.02,0.03,0.04,0.05,0.06,0.07,0.08,0.09,0.1,0.15,1]
             cmap_lin = matplotlib.pyplot.cm.gray
             cmap_nonlin = nlcmap(cmap_lin, colourmap_levels)

             ThreeD_spectrum_axis.plot_surface(X,Y,Z, rstride=5, cstride=5, cmap=matplotlib.pyplot.cm.gray, linewidth=0, antialiased=True)

но я получаю сообщение об ошибке: «поднять ValueError («Цветовая карта% s не распознана»% имя) ValueError: Colormap ‹main объект .nlcmap по адресу 0x06E81AF0> не распознан"

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

Есть ли другой способ получить нелинейное отображение цвета для поверхностного графика?

ИЗМЕНИТЬ:

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

matplotlib.colors.Normalize(vmin=numpy.amin(Z), vmax=0.05)

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

Можно ли каким-либо образом изменить количество уровней дискретизации трехмерного контурного графика?


person Community    schedule 29.07.2015    source источник


Ответы (1)


Я думаю, вам нужно создать экземпляр ColorMap.

Здесь есть несколько возможностей.

Вы можете создать новую карту, например, изменив гамму.

cmap =  matplotlib.colors.LinearSegmentedColormap('my_cmap', dictionary, N=256, gamma=1.0)

или используя список [ (value, color), (value,color) ]:

matplotlib.colors.from_list(name, colors, N=256, gamma=1.0)

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

cm = matplotlib.cm.ScalarMappable( ... )

с вашей собственной функцией Normalize. Я думаю, что тогда карта будет распознана.

person Sanjay Manohar    schedule 29.07.2015
comment
Спасибо, Санджай, использование функции Normalize и ScalarMappable обеспечивает решение. то есть matplotlib.colors.Normalize (vmin = numpy.amin (Z), vmax = 0,15) - person ; 30.07.2015