颜色简史 python色彩设置

需求背景:丁丁猫的娃们学习python turtle和数据可视化的各种统计图形时遇到设置颜色的问题。好奇心是最好的老师,电脑是如何生成颜色的?好问题也许会唤起某个孩子的好奇心,沿着好奇心进入自由自在地畅游!丁丁猫的图书角将迎接小学员们在此畅游。喜欢可视化的小朋友将看到顶尖设计师游刃有余地运用颜色表达情绪、观点和印象深刻的事实。
image

一本经典好书,是一门学科的门把手,抓住了就能进到殿堂,也顺手堵上了各类自编教材和考级证的财路

image
颜色简史 牛顿用棱镜验证了光色混合的原理,破解了困扰了人类几千年的颜色之谜。可惜他只摸到了第一把钥匙。他后半生一直困扰于,按照自己的理论,何以用颜料怎样都混不出白色。无数失败的实验一直做到去世。因为他没有意识到光色混合和减色混合的区别。一直在相反的方向上在寻找答案。第二把钥匙在他死后的几年后被一名德国版画家 Le Blon 拿到。他第一次确定了减色混合的三原色是红蓝黄,此三色可以混合出黑色以及所有颜色,以此成功实验了最低成本的套色印刷。且首次提出了加色混合 impalpable color 和减色混合 material color 的区别。
image

别说后者,仅将原色缩减为三种就已是革命性的里程碑。上述两个颜色理论里最重要的发现都发生于1700s~1730s年间。往前退三四百年,首次提出的原色是Aristotelian:五种,红橙紫绿蓝。然后最接近的是达芬奇:白黄绿蓝紫黑。可惜他黑白也算在原色里,否则他就能发现色轮(将原色按环形排列)绿色不再被认为是原色,依赖于色料工艺的进步,因为它很难混得到!直到今天,艺术家们也需要下功夫学习如何混出自己想要的绿色。这里有一个关键性知识点。画家们通常用六原色来混色(三原色分别有冷暖版本)相对靠近的原色混出来intense间色,相对远离的原色混出来 muted 间色。这里绿色的两个版本差距最大。只有冷黄+G蓝能混出鲜亮的绿色,暖黄+R蓝只能混出韭菜花 。

image
甚至比韭菜花还难看的酱泥色。而纯的蓝色是贵而难得的。如果用群青普蓝是基本不可能混出正绿的。即使是钴蓝天蓝这种偏冷的蓝,颜料不好(透明度不高,色料不纯)也混不出来。颜料不发达的年代,人们会认为绿色属于原色(无法通过混合得到)是很正常的。水彩混绿色尤其难。我做了一些混色试验,DS 家的群青PB29和钴蓝PB28,与冷黄PY150,都只能混出很灰很灰的绿。这是世界上最好的水彩厂商的最常用蓝色。 人类认识颜色的两大工具,一个是色轮,解决了Hue的所有谜团。另一个是 HSL(Munsell color system)一直到1930s 才被发明。简直是天才!
image

往水彩颜料里加水,降低的到底是饱和度还是明度这个困扰我很久的问题,我看了这张图才明白
image

补一下基础背景。加色混合(光色混合)越多颜色叠加越接近白色。就是牛顿棱镜的反推。RGB颜色体系就源于此,显示器的显色原理。减色混合(颜料混合)越多颜色叠加越接近黑色。因颜料呈现颜色靠的是反射光,没吸收的波长就是我们看见的颜色。只反射绿色人眼看见的就是绿。CMYK、绘画、印刷的基础是饱和度。你按HSL那张图把色环升到最顶一层(白色)去理解。把水彩颜料画在不同灰度的纸上(或叠加在之前画过的颜色上)改变的是明度。所以水彩靠的是铺层。其他不透明颜料可以直接在混色时加入黑(灰)色改变明度。但水彩颜料的特殊属性不能这么干,加入灰色黑色会大幅度降低透明度,混出来泥浆色。

image

色彩理论或者说彩色视觉的发展,离不开物理学家,跟人类对光(波)的认识同步。牛顿走出了第一步。然后是提出了电场和磁场以波在空间中传播的Maxwel,他提出了RGB三原色,拍出了世界上第一张彩色照片(用滤色器拍的)。然后是双缝实验的托马斯杨(波粒二象性的基础),因他同时也是眼科医生,提出了假设表明“视觉系统以一种拮抗的方式解释颜色:红对绿,蓝对黄,黑对白”。在颜色学上这是非常重要的补色原理。也是LAB 色彩空间的基础。还解释了前面两位找不到答案的问题:“色盲”是如何产生的。

image

这是PS里的调色面板,包含了4种色彩模型。RGB和CMYK都非常直观,显示器用RGB,每种颜色的值对应一个16进位编码。例如#0000FF就是RGB空间里最纯的蓝色。HSB 和 HSL 原理相近,都源于Munsell孟塞尔颜色体系。但标尺不一样。难理解的是LAB。但它最符合人眼对色彩的感知构造 https://t.co/cEiA1XaAnKHSB和HSL的H代表Hue色相。孟塞尔把hue按红黄绿蓝紫分成十个大格,100个小格。说到色相该怎么划分区间,这里的莫名其妙跟音乐差不多。传统上把彩虹分为7色,但有的版本是青(cyan)蓝紫,有的版本是蓝靛(indigo)紫。音阶八度也划分为7区。实际是不同文化里,有四音的,五律的,钢琴调音用的还是12平均律

image

image

S都代表Saturation,译法有饱和度、彩度、纯度、色度 chroma。B是brightness,L是lightness,或V(value/tone),相关译法是明度、亮度、灰度。HSB(HSV) 和 HSL (HV/C) 的关键区别在于对饱和度的定义,对亮度的测量标尺。映射到三维色彩模型的话,前者是倒三角锥,后者算是个球型。
image
image

我随便找了两个颜色。左图是high chroma 极值的 Cyan。右图是个饱和度和亮度都中等水平的蓝色。HSL和HSB这两个模型描述它俩的数值是很不一样的。Cyan在HSL里亮度是50%,在HSB里是100。因为HSL里L的0100是从白到黑。HSB里B的0100是从纯黑到该色色相的最高纯度。反正知道两者不能完全互换就行了还有一个很重要的理论是瑞利散射。生物的进化会适应环境,而不是环境适应生物。瑞利散射导致大气层内的光谱在可见光上能量比较高。于是大多数地球生物,包括人类都会对这个区域敏感。不然,恐怕我们的色彩系统会变成一个完全不同的东西。


import matplotlib.colors as mcolors

def plot_colortable(colors, title, sort_colors=True, emptycols=0):
    cell_width = 212
    cell_height = 22
    swatch_width = 48
    margin = 12
    topmargin = 40

    # Sort colors by hue, saturation, value and name.

    by_hsv = ((tuple(mcolors.rgb_to_hsv(mcolors.to_rgba(color)[:3])), name)
                    for name, color in colors.items())

    if sort_colors is True:
        by_hsv = sorted(by_hsv)
    names = [name for hsv, name in by_hsv]

    n = len(names)
    ncols = 4 - emptycols
    nrows = n // ncols + int(n % ncols > 0)
    width = cell_width * 4 + 2 * margin
    height = cell_height * nrows + margin + topmargin

    dpi = 72

    fig, ax = plt.subplots(figsize=(width / dpi, height / dpi), dpi=dpi)
    fig.subplots_adjust(margin/width, margin/height,
                        (width-margin)/width, (height-topmargin)/height)

    ax.set_xlim(0, cell_width * 4)
    ax.set_ylim(cell_height * (nrows-0.5), -cell_height/2.)
    ax.yaxis.set_visible(False)
    ax.xaxis.set_visible(False)
    ax.set_axis_off()
    ax.set_title(title, fontsize=24, loc="left", pad=10)


    for i, name in enumerate(names):
        row = i % nrows
        col = i // nrows
        y = row * cell_height

        swatch_start_x = cell_width * col
        swatch_end_x = cell_width * col + swatch_width
        text_pos_x = cell_width * col + swatch_width + 7

        ax.text(text_pos_x, y, name, fontsize=14,
                horizontalalignment='left',
                verticalalignment='center')

        ax.hlines(y, swatch_start_x, swatch_end_x,
                  color=colors[name], linewidth=18)

    return fig

plot_colortable(mcolors.BASE_COLORS, "Base Colors",
                sort_colors=False, emptycols=1)

plot_colortable(mcolors.TABLEAU_COLORS, "Tableau Palette",
                sort_colors=False, emptycols=2)

#sphinx_gallery_thumbnail_number = 3
plot_colortable(mcolors.CSS4_COLORS, "CSS Colors")

# Optionally plot the XKCD colors (Caution: will produce large figure)
#xkcd_fig = plot_colortable(mcolors.XKCD_COLORS, "XKCD Colors")
#xkcd_fig.savefig("XKCD_Colors.png")

plt.show()

image.png
import os

import requests
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl

%matplotlib inline

plt.style.use("ggplot")

def plot_colormap(cmap_name):
    fig, ax = plt.subplots(figsize=(6, 2))
    cmap = mpl.cm.get_cmap(cmap_name)
    colors = cmap(np.linspace(0, 1, cmap.N))
    ax.imshow([colors], extent=[0, 10, 0, 1])
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_title(cmap_name)
plot_colormap("viridis")
plot_colormap("RdBu")
plot_colormap("rainbow")
image.png


cnames = {
'aliceblue':            '#F0F8FF',
'antiquewhite':         '#FAEBD7',
'aqua':                 '#00FFFF',
'aquamarine':           '#7FFFD4',
'azure':                '#F0FFFF',
'beige':                '#F5F5DC',
'bisque':               '#FFE4C4',
'black':                '#000000',
'blanchedalmond':       '#FFEBCD',
'blue':                 '#0000FF',
'blueviolet':           '#8A2BE2',
'brown':                '#A52A2A',
'burlywood':            '#DEB887',
'cadetblue':            '#5F9EA0',
'chartreuse':           '#7FFF00',
'chocolate':            '#D2691E',
'coral':                '#FF7F50',
'cornflowerblue':       '#6495ED',
'cornsilk':             '#FFF8DC',
'crimson':              '#DC143C',
'cyan':                 '#00FFFF',
'darkblue':             '#00008B',
'darkcyan':             '#008B8B',
'darkgoldenrod':        '#B8860B',
'darkgray':             '#A9A9A9',
'darkgreen':            '#006400',
'darkkhaki':            '#BDB76B',
'darkmagenta':          '#8B008B',
'darkolivegreen':       '#556B2F',
'darkorange':           '#FF8C00',
'darkorchid':           '#9932CC',
'darkred':              '#8B0000',
'darksalmon':           '#E9967A',
'darkseagreen':         '#8FBC8F',
'darkslateblue':        '#483D8B',
'darkslategray':        '#2F4F4F',
'darkturquoise':        '#00CED1',
'darkviolet':           '#9400D3',
'deeppink':             '#FF1493',
'deepskyblue':          '#00BFFF',
'dimgray':              '#696969',
'dodgerblue':           '#1E90FF',
'firebrick':            '#B22222',
'floralwhite':          '#FFFAF0',
'forestgreen':          '#228B22',
'fuchsia':              '#FF00FF',
'gainsboro':            '#DCDCDC',
'ghostwhite':           '#F8F8FF',
'gold':                 '#FFD700',
'goldenrod':            '#DAA520',
'gray':                 '#808080',
'green':                '#008000',
'greenyellow':          '#ADFF2F',
'honeydew':             '#F0FFF0',
'hotpink':              '#FF69B4',
'indianred':            '#CD5C5C',
'indigo':               '#4B0082',
'ivory':                '#FFFFF0',
'khaki':                '#F0E68C',
'lavender':             '#E6E6FA',
'lavenderblush':        '#FFF0F5',
'lawngreen':            '#7CFC00',
'lemonchiffon':         '#FFFACD',
'lightblue':            '#ADD8E6',
'lightcoral':           '#F08080',
'lightcyan':            '#E0FFFF',
'lightgoldenrodyellow': '#FAFAD2',
'lightgreen':           '#90EE90',
'lightgray':            '#D3D3D3',
'lightpink':            '#FFB6C1',
'lightsalmon':          '#FFA07A',
'lightseagreen':        '#20B2AA',
'lightskyblue':         '#87CEFA',
'lightslategray':       '#778899',
'lightsteelblue':       '#B0C4DE',
'lightyellow':          '#FFFFE0',
'lime':                 '#00FF00',
'limegreen':            '#32CD32',
'linen':                '#FAF0E6',
'magenta':              '#FF00FF',
'maroon':               '#800000',
'mediumaquamarine':     '#66CDAA',
'mediumblue':           '#0000CD',
'mediumorchid':         '#BA55D3',
'mediumpurple':         '#9370DB',
'mediumseagreen':       '#3CB371',
'mediumslateblue':      '#7B68EE',
'mediumspringgreen':    '#00FA9A',
'mediumturquoise':      '#48D1CC',
'mediumvioletred':      '#C71585',
'midnightblue':         '#191970',
'mintcream':            '#F5FFFA',
'mistyrose':            '#FFE4E1',
'moccasin':             '#FFE4B5',
'navajowhite':          '#FFDEAD',
'navy':                 '#000080',
'oldlace':              '#FDF5E6',
'olive':                '#808000',
'olivedrab':            '#6B8E23',
'orange':               '#FFA500',
'orangered':            '#FF4500',
'orchid':               '#DA70D6',
'palegoldenrod':        '#EEE8AA',
'palegreen':            '#98FB98',
'paleturquoise':        '#AFEEEE',
'palevioletred':        '#DB7093',
'papayawhip':           '#FFEFD5',
'peachpuff':            '#FFDAB9',
'peru':                 '#CD853F',
'pink':                 '#FFC0CB',
'plum':                 '#DDA0DD',
'powderblue':           '#B0E0E6',
'purple':               '#800080',
'red':                  '#FF0000',
'rosybrown':            '#BC8F8F',
'royalblue':            '#4169E1',
'saddlebrown':          '#8B4513',
'salmon':               '#FA8072',
'sandybrown':           '#FAA460',
'seagreen':             '#2E8B57',
'seashell':             '#FFF5EE',
'sienna':               '#A0522D',
'silver':               '#C0C0C0',
'skyblue':              '#87CEEB',
'slateblue':            '#6A5ACD',
'slategray':            '#708090',
'snow':                 '#FFFAFA',
'springgreen':          '#00FF7F',
'steelblue':            '#4682B4',
'tan':                  '#D2B48C',
'teal':                 '#008080',
'thistle':              '#D8BFD8',
'tomato':               '#FF6347',
'turquoise':            '#40E0D0',
'violet':               '#EE82EE',
'wheat':                '#F5DEB3',
'white':                '#FFFFFF',
'whitesmoke':           '#F5F5F5',
'yellow':               '#FFFF00',
'yellowgreen':          '#9ACD32'}

colorname = [k for k,v in cnames.items()]
print(colorname)
colorAll = [v for k,v in cnames.items()]
print(colorAll)

#2
import turtle
import random
from random import randint
color = ['red','orange','yellow','green','blue','pink','purple']

size = 20
circles = 20
turtle.speed(100)

turtle.color("red")

def move(length, angle):
    turtle.right(angle)
    turtle.forward(length)

def hex():
    turtle.pendown()
    c = random.choice(colorAll)
    turtle.color(c)
    turtle.begin_fill()
    for i in range(6):
        move(size,-60)
    turtle.end_fill()
    turtle.penup()

# start
turtle.penup()

for circle in range (circles):
    if circle == 0:
        hex()
        move(size,-60)
        move(size,-60)
        move(size,-60)
        move(0,180)
    for i in range (6):
        move(0,60)
        for j in range (circle+1):
            hex()
            move(size,-60)
            move(size,60)
            move(-size,0)
    move(-size,60)
    move(size,-120)
    move(0,60)

turtle.done()
#turtle.exitonclick()

颜色板九宫格的实现
子函数 正方形

import turtle as t
colors =['#e2d8e2', '#a8996c', '#2d281f',
    '#9facb1', '#e9daa9', '#684a24',
    '#5c6051', '#bb783b',  '#86a086',]

def square(l,c):
    t.color(c)
    t.begin_fill()
    for i in range(5):
        t.forward(l)
        t.right(90)
    t.end_fill()
    return #t.done()

主函数

def main_square(n,l,x,y):
    t.penup()
    t.goto(x,y)
    t.pendown()
    for i,c in enumerate(colors):

        t.penup()
        t.goto(x + (i%3)*l,y-(i//3)*l)
        t.pendown()
        t.left(90)
        square(l, c)

    return t.done()
n,l = 9,100
x,y = -200,100
print(main_square(n,l,x,y))
image.png

你可能感兴趣的:(颜色简史 python色彩设置)