Values lower and equal 1000/60 (16.6667) must have gradient from blue to green. Values greater than 1000/60 (16.6667) must have gradient from red to black. But values from 16.67 to 16.70 are blue instead red. Why? How make them red?
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')
Image Result
CodePudding user response:
Internally, the colormap is represented by a list of colors. Default, there are 256 colors in that list. LinearSegmentedColormap.from_list
has a parameter N=
to set a different number of colors. Depending on how precise you need the color ranges to be, you'd need a larger number.
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", colors, N=10000)