Matplotlib\Seaborn 使用自定义颜色图的浮点数据颜色错误

Matplotlib\Seaborn wrong colors on float data with custom colormap

小于等于 1000/60 (16.6667) 的值必须具有从蓝色到绿色的渐变。 大于 1000/60 (16.6667) 的值必须具有从红色到黑色的渐变。 但是从 16.67 到 16.70 的值是蓝色而不是红色。 为什么?如何让它们变红?

example image

import glob
import os
import subprocess
import sys

import matplotlib.colors
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from PIL import Image, ImageEnhance, ImageChops, ImageDraw, ImageFilter

Image.MAX_IMAGE_PIXELS = None
pd.options.display.float_format = '{:.2f}'.format
np.set_printoptions(suppress=True, precision=2)

# Open image in end
def openImage(path):
    imageViewerFromCommandLine = {'linux': 'xdg-open',
                                  'win32': 'explorer',
                                  'darwin': 'open'}[sys.platform]
    subprocess.run([imageViewerFromCommandLine, path])


test_data = np.arange(16.60, 16.81, 0.01)
test_data = np.resize(test_data, (3, 7))

line_legend = (1000 / 29, 16.66, 16.00, 0)
line_legend_last = len(line_legend) - 1

# norm for colormap from 0 to 1000/29
norm = matplotlib.colors.Normalize(line_legend[line_legend_last], line_legend[0], clip=True)

# custom colors
colors = [[0.0, "lime"],
          [norm(16.00), "green"],
          [norm(16.66), "blue"],
          [norm(16.67), "red"],
          [1.0, "black"]]
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", colors)

# color bar range and labels
cbar_kws = {"orientation": "vertical",
            "shrink": 1,
            'extend': 'both',
            "ticks": line_legend,
            "drawedges": False,
            }

ax = sns.heatmap(test_data, linewidths=0.1, linecolor='gainsboro', cmap=cmap, xticklabels=1, yticklabels=1, square=True,
                 cbar=True, annot=True, fmt='g', cbar_kws=cbar_kws, robust=True,
                 vmin=line_legend[line_legend_last], vmax=line_legend[0])

plt.savefig(r'D:\result_wrong_colors.png')

openImage(r'D:\result_wrong_colors.png')

图像结果

在内部,颜色图由颜色列表表示。默认情况下,该列表中有 256 种颜色。 LinearSegmentedColormap.from_list 有一个参数 N= 来设置不同数量的颜色。根据您需要颜色范围的精确程度,您需要更大的数字。

cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", colors, N=10000)