十六进制颜色代码是如何工作的?/ 如何实现类似热图的东西

3 投票
3 回答
7058 浏览
提问于 2025-04-17 08:35

我正在用Python的turtle库写一个简单的程序,目的是在一些固定点周围画圆圈。不过,我想让这个程序看起来像个热图,颜色随着离原点的距离变得“冷”一些。我的想法是从基础的白色#FFFFFF开始,根据距离减去一个百分比。

我原以为十六进制颜色代码是通过降低它的十六进制值来让颜色变得“冷”,但我现在了解到,前两个数字代表红色的值,第二个代表绿色,最后一个代表蓝色。那么,我该如何实现我想要的热图效果呢?

我相信距离计算是正确的,只是我对颜色代码的使用方式不太对。我写的用于颜色计算的函数是:

def findColor(dist):
    base = "FFFFFF"
    num = int(base, 16)
    percent = dist/800 #800 is the max distance away
    newNum = (num - (num*percent))
    color = hex(int(newNum))
    return color

我得到的热图结果是:

circle heat map

在Ignacio Vazquez-Abrams的帮助下,关于HSV的知识,我让它看起来像这样 :) :

Updated color algorithm

3 个回答

1

这里有一段代码,可以用来生成任何多色渐变。默认的渐变是从白色到红色,再到绿色,接着是蓝色,最后到黑色,不过你可以很容易地把它改成其他的渐变。

在这个代码中,'d'这个参数的范围是从0到1,所以如果你有更大的距离,可能需要把它缩小一下,才能在这个函数里使用。

这段代码使用RGB颜色格式,但为了让渐变效果更好,它会把颜色转换成HSV格式。

import colorsys
import math

GRADIENT_SPEC = [
    (1.0, 1.0, 1.0),  # white
    (1.0, 0.0, 0.0),  # red
    (0.0, 1.0, 0.0),  # green
    (0.0, 0.0, 1.0),  # blue
    (0.0, 0.0, 0.0)]  # black

def gradient(d, spec=GRADIENT_SPEC):
    N = len(spec)
    idx = int(d * (N - 1))
    t = math.fmod(d * (N - 1), 1.0)
    col1 = colorsys.rgb_to_hsv(*spec[min(N - 1, idx)])
    col2 = colorsys.rgb_to_hsv(*spec[min(N - 1, idx + 1)])
    hsv = tuple(a * (1 - t) + b * t for a, b in zip(col1, col2))
    r, g, b = colorsys.hsv_to_rgb(*hsv)
    return '#%02X%02X%02X' % (r * 255, g * 255, b * 255)

for x in xrange(12):
    print x, gradient(x / 10.0)
1

这个技巧是要分别处理三个字节。让我试着重新写一下你的函数,按照我认为应该的方式来做:

def findColor(dist):
    base = 0xFFFFFF
    percent = dist/800 #800 is the max distance away
    hexpercent = 0xFF - (percent * 0xFF)
    first = (base & 0xFF0000) >> 16
    second = (base & 0xFF00) >> 8
    third = base & 0xFF
    color = hex(((first - hexpercent) << 16) | ((second - hexpercent) << 8) | (third - hexpercent))
    return color

我会把每个字节单独拿出来,从每个字节中减去百分比,然后再把这些字节组合成一个整数。可能还有更聪明的方法来做到这一点,但这样做应该能给你一个稳定的灰度渐变。(如果你想要红色、绿色或蓝色的稳定渐变,可以只处理 0xFF00000xFF000xFF。)

需要注意的是,这个方法没有考虑到颜色的任何生理特性——可能还有更“好看”的处理方式。(实际上,颜色专家对计算机科学家选择的网络安全颜色感到非常不满,因为这些颜色是基于“数字”来决定的……)

4

你想用 HSV 这种颜色模式来代替RGB,来表示颜色;可以在色相的范围内滑动来表示你的距离。colorsys 这个库可以帮你实现。

撰写回答