11# Color Harmonies
22
3- In color theory, color harmony refers to the property that certain aesthetically pleasing color combinations have.
4- Modern day color theory probably starts with the first color wheel created by Isaac Newton. Based on his observations of
5- light with prisms, he formed one the first color wheels. From there, many others built upon this work, sometimes with
6- opposing ideas.
3+ Isaac Newton, based on his observations of light interacting with prisms, constructed the first known color wheel. From
4+ there, many others built upon this work, sometimes with opposing ideas, but his original work is where color harmony got
5+ its start.
76
87The original color wheel, while inspired by what was observed by light, was created based on experiments with pigments
9- as well. As most know, in paint, red, yellow, and blue are considered primary colors. Newton thought this translated to
10- light as well and stated they were also the primary colors of light. While this isn't actually true, his work was very
11- important in reshaping how people viewed color.
8+ as well. In paints, red, yellow, and blue are often taught to be primary colors. This idea originates from Newton's
9+ work as through his experiments, he came to the conclusions that all colors could be made from red, yellow, and blue,
10+ and assumed this was true for light as well. While this isn't exactly true, his work was very important in reshaping how
11+ people viewed color.
1212
1313Over time, the color wheel was refined. The traditional model, which we will call an RYB color model, defined 12 colors
1414that made up the wheel: the primary colors, the secondary colors, and the tertiary colors. The secondary colors are
1515created by evenly mixing the primary colors, and the tertiary colors are created by evenly mixing those primary colors
1616with the secondary colors.
1717
18- ``` py play wheel
19- Color(' ryb' , [1 , 0 , 0 ]).harmony(' wheel' , space = ' ryb' )
18+ ``` py play
19+ Wheel( Color(' ryb' , [1 , 0 , 0 ]).harmony(' wheel' , space = ' ryb' ) )
2020```
2121
22- The idea of color harmonies originates from the idea that colors, based on their relative position on the wheel, can
23- form more pleasing color combinations.
22+ The concept of color harmonies was formulated on the idea that colors, based on specific, relative position on the
23+ wheel, can form more pleasing color combinations.
2424
2525## Which Color Space is Best for Color Harmonies?
2626
27- As we know, these days, there are many color spaces out there: subtractive models, additive models, perceptually
28- uniform models, high dynamic range models, etc. Many color spaces trying to solve specific issues based on the knowledge
29- at the time.
27+ These days, there are many color spaces and models out there: subtractive models, additive models, perceptually
28+ uniform models, high dynamic range models, etc. But which space/model is the best for color harmonies?
29+
30+ The concept of primary colors stems from the idea that there are a set of pure colors from which all colors can be made
31+ from. The primary colors of electronic screens use red, green, and blue light to display its full gamut of color.
32+ Interestingly, electronic screens were modeled after the human eye that have three cones, each sensitive to wavelengths
33+ close to red, green, and blue. From what the three cones in the eye detect, our brain perceive all the various colors.
3034
31- It should be noted, that the idea of primary colors stems from the idea that there are a set of pure colors from which
32- all colors can be made from. If you've spent any time with paint, you will know that not all colors can be made from
33- red, yellow, and blue. There are colors like ` #!color cyan ` and ` #!color magenta ` that cannot be made with the
34- traditional primary colors. The early work that helped create the first color wheels was done with the limited paints
35- that was available at the time, and the color harmony concepts were built upon the early RYB color model. Modern
36- printers actually use primary colors of ` #!color magenta ` , ` #!color yellow ` , and ` #!color cyan ` .
35+ Paints and inks on the other hand can alter the light that comes back to our eye depending on the medium's light
36+ absorption and scattering properties. These physical properties of the medium can alter what light is reflected back to
37+ our eyes causing how our eyes perceive the mixing of colors in paint. This mixing behavior in pigments can seem different
38+ when compared to how pure light mixes.
3739
38- In modern TVs and monitors, the RYB color model is not used. Paint has subtractive properties, but light has additive
39- properties. Electronic screens create all their colors with light based methods that mix red, green, and blue lights. In
40- addition, the human eye perceives colors using red, green , and blue light as well. As far as light is concerned, the
41- primary colors are red, green, and blue.
40+ The work that helped create the first color wheel was done with the limited paints that were available at the time, and
41+ influenced by the light scattering and absorption properties of those paints. Because of this, the original color wheel
42+ is built on the RYB color model which uses red, yellow , and blue as the primary colors. The question though, is would
43+ our theories on color harmony be different today if early theorists had a better understanding of light and color?
4244
43- In reality, we could create a color wheel from any of the various color spaces out there and end up with different
44- results. If we were to compose a color wheel based on the common sRGB color space, we could base it off the 3 primary
45- colors of light. Starting with red (0˚), we could extract the colors at evenly spaced degrees, 30˚ to be exact. This
46- would give us our 12 colors for the sRGB color space.
45+ In reality, we can create a color wheel from any of the various color spaces out there and end up with different
46+ results based on how color is spaced and oriented within those spaces. As an example, we could create one directly from
47+ the sRGB color space. The sRGB space is an additive color space that was modeled on light behavior, so its primary
48+ colors are red, green, and blue. We can simply select the most red, green, and blue colors in its gamut, and transform
49+ them into a polar space such as HSL. Here, these colors are evenly spaced and if we mixed these colors evenly, and those
50+ colors evenly, we will get 12 colors whose hues are evenly spaced at 30˚.
4751
4852``` py play
4953Steps([Color(' hsl' , [x, 1 , 0.5 ]) for x in range (0 , 360 , 30 )])
5054```
5155
5256From this we can construct an sRGB color wheel.
5357
54- ``` py play wheel
55- Color(' red' ).harmony(' wheel' , space = ' srgb' )
58+ ``` py play
59+ Wheel( Color(' red' ).harmony(' wheel' , space = ' srgb' ) )
5660```
5761
58- This is different from the RYB color wheel we showed earlier, and more accurate in relation to how light works, but does
59- it yield better harmonies for colors?
62+ These results are different from the RYB color wheel we showed earlier, but are used to display all the colors you see
63+ on your screen right now. This is how light works when not scattered and absorbed by pigments, but does that mean that
64+ this color wheel yields better color harmonies?
6065
61- The sRGB color space is additive, just like light, but pigments are subtractive. We can use CMY to generate a
62- subtractive wheel with a far greater range that red, green blue creates by use magenta, yellow, and cyan. But does this
63- create better harmonies?
66+ We can transform the RGB color model into a subtractive color space, something similar to what printers use when
67+ applying ink to paper. Printers use something closer to an RYB model and use magenta, yellow, and cyan.
6468
6569``` py play
66- Steps(Color(' magenta' ).harmony(' wheel' , space = ' cmy' ))
67- ```
68-
69- ``` py play wheel
70- Color(' magenta' ).harmony(' wheel' , space = ' cmy' )
70+ Wheel(Color(' magenta' ).harmony(' wheel' , space = ' cmy' ))
7171```
7272
73- If we were to select the perceptually uniform OkLCh color space, and seed it with red's lightness and chroma, we'd get
74- the wheel below.
73+ If we were to select the perceptually uniform OkLCh color space, and seed it with red's lightness and chroma, we'd once
74+ again get very different results in the color wheel. The results are more similar to when we used sRGB, but the exact
75+ hues may be different and lightness is kept more uniform when we construct the wheel. But does that mean this model is
76+ better?
7577
7678``` py play
77- Steps (Color(' red' ).harmony(' wheel' , space = ' oklch' ))
79+ Wheel (Color(' red' ).harmony(' wheel' , space = ' oklch' ))
7880```
7981
80- ``` py play wheel
81- Color(' red' ).harmony(' wheel' , space = ' oklch' )
82- ```
83-
84- This produces colors with visually more uniform lightness, does that mean these are better?
85-
86- The truth is, what is better or even harmonious can be largely subjective, and everyone has reasons for selecting
87- certain color spaces for a specific task.
82+ The truth is that what is better or even harmonious can be largely subjective.
8883
89- Many artists swear by the limited, classical color wheel, others are fine with using the RGB color wheel as it is easy
90- to work with in CSS via the HSL color space, and there are still others that are more interested in perceptually uniform
91- color spaces that aim for more consistent hues and predictable lightness.
84+ Many artists swear by the limited, classical RYB color wheel, and others are fine with using the sRGB color wheel as it
85+ is easy to work with in CSS via the HSL color space, and models closer to how the eye works. Additionally, there may be
86+ some that prefer a perceptually uniform approach that aims for more consistent hues and predictable lightness.
9287
9388As far as ColorAide is concerned, we've chosen to use OkLCh as the color space in which we work in. This is based
9489mainly on the fact that it keeps hue more consistent than some other options, and it allows us to support a wider gamut
@@ -100,7 +95,9 @@ Steps(Color.steps(['black', 'blue', 'white'], steps=11, space='hsl'))
10095Steps(Color.steps([' black' , ' blue' , ' white' ], steps = 11 , space = ' lch' ))
10196```
10297
103- While OkLCh is the default, we understand that there are many reasons to use other spaces, so use what you like, we
98+ While OkLCh is the default, we make no assertions that this is better than using any other color space. If you are from
99+ the world of paint, you may strongly dislike this default and prefer a classical RYB approach, or maybe you just want to
100+ use the familiar sRGB approach. We understand that there are many reasons to use other spaces, so use what you like, we
104101won't judge :smile : . If you are a color theory purist, you can use the classical RYB model.
105102
106103``` py play
@@ -115,14 +112,14 @@ harmonies, make sure you are working directly within RYB to ensure you are not o
115112///
116113
117114/// tip
118- ` harmony() ` can output the results in any color space you need by setting ` out_space ` .
115+ Regardless of what color space ` harmony() ` operates in, it can output the results in any color space you need by setting
116+ ` out_space ` .
119117
120118``` py play
121119Steps(Color(' red' ).harmony(' complement' , out_space = ' srgb' ))
122120```
123121///
124122
125-
126123## Supported Harmonies
127124
128125ColorAide currently supports 7 theorized color harmonies: [ monochromatic] ( #monochromatic ) ,
@@ -224,17 +221,13 @@ Steps(Color('red').harmony('rectangle'))
224221### Others
225222
226223If you have a particular configuration that you are after that is not covered with the default harmonies, you can use
227- ` harmony ` to calculate your own via ` wheel ` . The ` wheel ` harmony that can generate a color wheel of any size. Simply use
228- a color to seed the wheel, specify the space in which to generate the wheel, and optionally, provide the desired number
229- of colors in the color wheel via the ` count ` argument. With this, we can generate a wheel for any color (assuming the
230- color space can properly handle the color). We can even generate an extended color wheel if so desired. This can allow
231- you to select hues at any interval you need.
232-
233- ``` py play wheel
234- Color(' ryb' , [1 , 0 , 0 ]).harmony(' wheel' , space = ' ryb' , count = 48 )
235- ```
224+ ` harmony ` to calculate your own via ` wheel ` . The ` wheel ` harmony that can generate a wheel of evenly spaced colors of
225+ any size. From this, additional harmonies could be calculated. Simply use a color to seed the wheel, specify the space
226+ in which to generate the wheel, and optionally, provide the desired number of colors in the color wheel via the ` count `
227+ argument. With this, we can generate a wheel of any size for any color.
236228
237229``` py play
230+ Wheel(Color(' ryb' , [1 , 0 , 0 ]).harmony(' wheel' , space = ' ryb' , count = 48 ))
238231Steps(Color(' ryb' , [1 , 0 , 0 ]).harmony(' wheel' , space = ' ryb' , count = 48 ))
239232```
240233
@@ -246,14 +239,14 @@ Non-cylindrical space support was added in 2.7.
246239
247240If you'd like to change the ` #!py3 Color() ` class's default harmony color space, it can be done with
248241[ class override] ( ./color.md#override-default-settings ) . Simply derive a new ` #!py3 Color() ` class from the original and
249- override the ` HARMONY ` property with the name of a suitable color space. Color spaces must be either a cylindrical
250- space, a Lab-like color space, or what we will call a regular, rectangular space. By "regular" we mean a normal 3
251- channel color space _ usually_ with a range of [ 0, 1] . Afterwards, all color harmony calculations will use the specified
252- color space unless overridden via the method's ` space ` parameter.
242+ override the ` HARMONY ` property with the name of a suitable color space. Color spaces must be a registered color space
243+ of either a cylindrical space, a Lab-like color space, or what we will call a regular, rectangular space. By "regular"
244+ we mean a normal 3 channel color space _ usually_ with a range of [ 0, 1] (think RGB) . Afterwards, all color harmony
245+ calculations will use the specified color space unless overridden via the method's ` space ` parameter.
253246
254247``` py play
255248class Custom (Color ):
256- HARMONY = ' hsl '
249+ HARMONY = ' ryb '
257250
258251Steps(Custom(' red' ).harmony(' split' ))
259252```
0 commit comments