Matplotlib более темная цветовая карта hsv
Я использую цветовую карту HSV из matplotlib для построения некоторых векторных полей. Есть ли способ затемнить или сделать более сглаженными цвета HSV, чтобы они выглядели больше так?
чем мои оригинальные цвета сюжета, которые слишком яркие:
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])
Ваше изображение будет:
методы
Я написал альтернативную реализацию поваренной книги 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)
Если вы хотите только затемнить зелень на изображении, вы можете сделать это (теперь все в одной строке):
pcol = ax.pcolormesh(x, y, z,
cmap=cmap_map(lambda x: x * [1, 0.7, 1],
plt.get_cmap('hsv'))
)