如何让Matplotlib单色顺序配色方案更鲜亮夺目?
如何让Matplotlib单色配色方案(如Blues/Reds)更鲜亮?
我想使用Matplotlib的单色配色方案(比如Blues、Reds),但希望颜色更"突出"——比如提升对比度、增加亮度,让蓝色和红色不再暗淡,达到类似HSV配色方案子集的鲜亮效果。以下是我的示例代码及当前输出:
import matplotlib.pyplot as plt import numpy as np import pandas as pd import seaborn as sns num_units_per_rf = 1000 # 模拟高斯分布数据 gaussian_place_cell_rf_list = [] gaussian_score_90_by_neuron_list = [] for place_cell_rf in np.arange(start=1, stop=4, step=0.5): score_90_by_neuron = np.random.normal(loc=place_cell_rf, size=num_units_per_rf) gaussian_score_90_by_neuron_list.append(score_90_by_neuron) gaussian_place_cell_rf_list.append(np.full(fill_value=place_cell_rf, shape=num_units_per_rf)) gaussian_df = pd.DataFrame({ 'place_cell_rf': np.concatenate(gaussian_place_cell_rf_list), 'score_90_by_neuron': np.concatenate(gaussian_score_90_by_neuron_list), }) noise_place_cell_rf_list = [] noise_score_90_by_neuron_list = [] for place_cell_rf in np.arange(start=1, stop=4, step=0.5): score_90_by_neuron = np.random.normal(loc=-place_cell_rf, size=num_units_per_rf) noise_score_90_by_neuron_list.append(score_90_by_neuron) noise_place_cell_rf_list.append(np.full(fill_value=place_cell_rf, shape=num_units_per_rf)) noise_df = pd.DataFrame({ 'place_cell_rf': np.concatenate(noise_place_cell_rf_list), 'score_90_by_neuron': np.concatenate(noise_score_90_by_neuron_list), }) fig, ax = plt.subplots(figsize=(12, 8)) # 绘制高斯分布和噪声数据的累积KDE g = sns.kdeplot( data=gaussian_df, x='score_90_by_neuron', common_norm=False, # 确保每个分组单独归一化 cumulative=True, hue='place_cell_rf', palette='Reds', ax=ax) sns.kdeplot( data=noise_df, x='score_90_by_neuron', common_norm=False, # 确保每个分组单独归一化 cumulative=True, hue='place_cell_rf', palette='Blues', ax=g) plt.show()
当前输出

期望效果
- 期望蓝色效果:

- 期望红色效果:

解决方案
方法1:截断配色映射,跳过暗淡浅色范围
Matplotlib的单色colormap(如Blues、Reds)通常从浅到深渐变,截取其中颜色更饱和的后半段,直接跳过开头的暗淡浅色:
# 获取分组数量 num_groups = len(gaussian_df['place_cell_rf'].unique()) # 截断Blues配色,只取0.3到1的范围 bright_blues = plt.cm.Blues(np.linspace(0.3, 1, num_groups)) # 截断Reds配色,只取0.3到1的范围 bright_reds = plt.cm.Reds(np.linspace(0.3, 1, num_groups)) # 绘图时替换palette参数 g = sns.kdeplot( data=gaussian_df, x='score_90_by_neuron', common_norm=False, cumulative=True, hue='place_cell_rf', palette=bright_reds, ax=ax) sns.kdeplot( data=noise_df, x='score_90_by_neuron', common_norm=False, cumulative=True, hue='place_cell_rf', palette=bright_blues, ax=g)
方法2:调整颜色的饱和度与亮度
借助colorsys模块将RGB转为HSV格式,针对性提升饱和度和亮度后再转回RGB:
import colorsys def brighten_colormap(cmap_name, num_colors, saturation_factor=1.5, brightness_factor=1.2): cmap = plt.get_cmap(cmap_name) colors = [] # 跳过最浅的配色段,从0.2开始取色 for i in np.linspace(0.2, 1, num_colors): rgb = cmap(i)[:3] # 提取RGB值,忽略alpha通道 hsv = colorsys.rgb_to_hsv(*rgb) # 调整参数,确保不超过HSV的取值范围(0-1) new_hsv = ( hsv[0], min(hsv[1] * saturation_factor, 1.0), min(hsv[2] * brightness_factor, 1.0) ) new_rgb = colorsys.hsv_to_rgb(*new_hsv) colors.append(new_rgb) return colors # 生成鲜亮的红、蓝配色 num_groups = len(gaussian_df['place_cell_rf'].unique()) bright_reds = brighten_colormap('Reds', num_groups) bright_blues = brighten_colormap('Blues', num_groups) # 绘图时使用自定义配色即可
方法3:用Seaborn生成HSV基准的鲜亮渐变
利用Seaborn的dark_palette/light_palette,指定input='hsv'生成基于HSV空间的高饱和度配色:
num_groups = len(gaussian_df['place_cell_rf'].unique()) # 生成鲜亮红色渐变(从亮红到深红) bright_reds = sns.dark_palette('#ff3333', n_colors=num_groups, reverse=False, input='hsv') # 生成鲜亮蓝色渐变(从亮蓝到深蓝) bright_blues = sns.dark_palette('#3333ff', n_colors=num_groups, reverse=False, input='hsv') # 替换绘图时的palette参数
方法4:直接从HSV空间生成单色渐变
如果想要完全复刻HSV的鲜亮感,直接从HSV空间生成固定色调、高饱和度的渐变:
def get_hsv_monochromatic(hue, num_colors, start_val=0.5, end_val=1.0): colors = [] # 固定饱和度为1,只调整亮度值 for val in np.linspace(start_val, end_val, num_colors): rgb = colorsys.hsv_to_rgb(hue, 1.0, val) colors.append(rgb) return colors # 红色的hue约为0,蓝色约为0.67 num_groups = len(gaussian_df['place_cell_rf'].unique()) bright_reds = get_hsv_monochromatic(0, num_groups) bright_blues = get_hsv_monochromatic(0.67, num_groups) # 绘图时使用该配色
内容的提问来源于stack exchange,提问作者Rylan Schaeffer
相关产品推荐
相关产品推荐

