Цветная карта Matplotlib темнее hsv

Я использую цветовую карту HSV из matplotlib для построения некоторых векторных полей. Есть ли способ затемнить или сделать более гладкими цвета HSV, чтобы они выглядели примерно так?

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

чем мои исходные цвета сюжета, которые слишком яркие:

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


person PerroNoob    schedule 09.07.2015    source источник
comment
Ознакомьтесь с первым разделом здесь: wiki.scipy.org/Cookbook/Matplotlib/ColormapTransformations   -  person farenorth    schedule 09.07.2015
comment
Я думаю, что комментарий выше действительно дает ответ здесь. Было бы хорошо написать об этом в ответе - я подумал, что сначала прокомментирую, чтобы узнать, хотят ли @farenorth или OP это сделать. Если нет, я что-нибудь напишу, но я не хочу красть вероятные голоса, которые вы получите;)   -  person J Richard Snape    schedule 13.07.2015
comment
Я предложил отредактировать этот вопрос. Я был уверен, что это сделало вопрос более конкретным и ясным (включая код MCVE !). Кто-нибудь еще хочет вмешаться? Была ли моя ревизия действительно слишком инвазивной?   -  person farenorth    schedule 14.07.2015
comment
Спасибо за ваши предложения. Эта ссылка кажется наиболее близким ответом, хотя цвета выглядят не так красиво, когда затемнены. В основном я думал о том, чтобы сделать цвета HSV более привлекательными (это субъективно, но цветовой круг более или менее отражает идею), но я думаю, что не указал это должным образом в своем вопросе. Я попробую ответить ниже и посмотрю, сработает ли я, чтобы принять его.   -  person PerroNoob    schedule 14.07.2015
comment
plt.get_cmap('rainbow') ближе к тому, что вы хотите?   -  person farenorth    schedule 14.07.2015
comment
Да, это выглядит намного лучше, но я отображаю векторное поле, поэтому мне нужно определение HSV на 360 градусов.   -  person PerroNoob    schedule 14.07.2015
comment
Ваш вопрос очень расплывчатый и, как вы заметили, субъективен. Вы продолжаете говорить «отображение векторного поля», но я думаю, что вы имеете в виду, что вы «отображаете направление вектора». Было бы полезно использовать MCVE. Вы смотрели на этот вопрос ?   -  person farenorth    schedule 14.07.2015
comment
Да, я имел в виду направление, извините за мой английский, я думаю, что не объяснился должным образом. Эта цветовая карта выглядит намного лучше, я попробую, но для нее по-прежнему требуется внешняя библиотека для построения графиков, такая как Seaborn. Сначала я попытался сделать вопрос коротким, так как отображение направлений вектора в цветовую палитру HSV не очень просто, а мой код длинный, поэтому это усложнило бы пост. Я просто подумал, что будет простой способ преобразовать цветовую карту HSV, и самый близкий ответ — ваша первая предложенная ссылка. Но да, это превратилось в нечто более сложное :)   -  person PerroNoob    schedule 14.07.2015
comment
Я не знал о husl , выглядит лучше. Я думаю, что попробую этот пакет pypi.python.org/pypi/husl , так как я m делаю vector direction --> HSV --> RGB и могу использовать RGB для HUSL   -  person PerroNoob    schedule 14.07.2015


Ответы (1)


Введение

Предполагая, что вы пытаетесь построить изображение pcolor следующим образом:

import numpy as np
import matplotlib.pyplot as plt

y, x = np.mgrid[slice(-3, 3 + 0.05, 0.05),
                slice(-3, 3 + 0.15, 0.15)]
z = (1 - x / 2. + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
# x and y are bounds, so z should be the value *inside* those bounds.
# Therefore, remove the last value from the z array.
z = z[:-1, :-1]

fig = plt.figure(1)
fig.clf()
ax = plt.gca()
pcol = ax.pcolormesh(x, y, z, cmap=plt.get_cmap('hsv'), )
plt.colorbar(pcol)
ax.set_xlim([-3, 3])
ax.set_ylim([-3, 3])

Ваш образ будет:

цветовая карта HSV.

Методы

Я написал альтернативную реализацию функции поваренной книги MPL cmap_map, которая изменяет цветовые карты. Помимо поддержки соответствия kwargs и pep8, эта версия обрабатывает разрывы в палитре:

import numpy as np
from matplotlib.colors import LinearSegmentedColormap as lsc


def cmap_map(function, cmap, name='colormap_mod', N=None, gamma=None):
    """
    Modify a colormap using `function` which must operate on 3-element
    arrays of [r, g, b] values.

    You may specify the number of colors, `N`, and the opacity, `gamma`,
    value of the returned colormap. These values default to the ones in
    the input `cmap`.

    You may also specify a `name` for the colormap, so that it can be
    loaded using plt.get_cmap(name).
    """
    if N is None:
        N = cmap.N
    if gamma is None:
        gamma = cmap._gamma
    cdict = cmap._segmentdata
    # Cast the steps into lists:
    step_dict = {key: map(lambda x: x[0], cdict[key]) for key in cdict}
    # Now get the unique steps (first column of the arrays):
    step_list = np.unique(sum(step_dict.values(), []))
    # 'y0', 'y1' are as defined in LinearSegmentedColormap docstring:
    y0 = cmap(step_list)[:, :3]
    y1 = y0.copy()[:, :3]
    # Go back to catch the discontinuities, and place them into y0, y1
    for iclr, key in enumerate(['red', 'green', 'blue']):
        for istp, step in enumerate(step_list):
            try:
                ind = step_dict[key].index(step)
            except ValueError:
                # This step is not in this color
                continue
            y0[istp, iclr] = cdict[key][ind][1]
            y1[istp, iclr] = cdict[key][ind][2]
    # Map the colors to their new values:
    y0 = np.array(map(function, y0))
    y1 = np.array(map(function, y1))
    # Build the new colormap (overwriting step_dict):
    for iclr, clr in enumerate(['red', 'green', 'blue']):
        step_dict[clr] = np.vstack((step_list, y0[:, iclr], y1[:, iclr])).T
    return lsc(name, step_dict, N=N, gamma=gamma)

Реализация

Чтобы использовать его, просто определите функцию, которая будет изменять ваши цвета RGB по вашему желанию (значения из от 0 до 1) и подать его на вход cmap_map. Например, чтобы получить цвета, близкие к цветам на предоставленных вами изображениях, вы можете определить:

def darken(x, ):
   return x * 0.8

dark_hsv = cmap_map(darken, plt.get_cmap('hsv'))

А затем измените вызов pcolormesh:

pcol = ax.pcolormesh(x, y, z, cmap=dark_hsv)

Темнее HSV.

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

pcol = ax.pcolormesh(x, y, z,
                     cmap=cmap_map(lambda x: x * [1, 0.7, 1],
                                   plt.get_cmap('hsv'))
                    )

Затемнить только зеленый

person farenorth    schedule 14.07.2015