4

Sometimes when drawing a diagram, you want a certain number of similar objects of different colours, but the number might vary and you don't want to have to go through and manually define and assign all the colours individually, especially if you're iterating over a set of variables. Regardless of the quantity of objects, you want the transition of colours to appear smooth and evenly spaced, so that it flows and creates an illusion of natural progression.


This image is produced with a nice, simple \foreach loop. A template is shown below.
Each integer in the set is denoted \int and the colour at each iteration is \hue. The value of \int is applied to the name of each node, the corresponding x-coordinate, and the associated text (i.e., the label inside the circle): (\int) at (\int,0) {\int};. fill=\hue!50 The two variables are declared together:
\foreach \int/\hue
And then defined together for each iteration:
{1/red,2/orange,3/yellow,4/green,5/cyan,6/blue,7/violet}
So 1 is associated with red, 2 with orange, and so on.
fill=\hue!20,color=\hue It's probably not perfect because we're using the predefined colours, but you get the idea. Something similar (more complex, modulates saturation) can be seen here, but I was never quite able to understand it. I'd prefer to adjust hue only, not saturation. Saturation is already easily adjusted by appending a ! value to the colour, (e.g., \hue!20).


\documentclass[margin=10]{standalone}
\usepackage{tikz}

\begin{document}
    \begin{tikzpicture}
        \foreach \int/\hue in 
        {1/red,2/orange,3/yellow,4/green,5/cyan,6/blue,7/violet}
            \node[draw,circle,color=black,fill=\hue!50] 
            (\int) at (\int,0) {\int};
    \end{tikzpicture}
\end{document}

To help illustrate what I want to achieve, here are some reference diagrams from LightColourVision. Notice how the saturation is uniform, and the spectrum is evenly divided at every stage.

enter image description here enter image description here


The idea is probably best summed up as such:

Automatic coloring may be useful in graphics or chart applications, where a potentially large and unspecified number of colors are needed, and the user does not want or is not able to specify each individual color.xcolor manual

Here's my best attempt so far:

\documentclass[rgb,tikz,dvipsnames,margin=10]{standalone}
\begin{document}
\definecolorseries{wheel}{hsb}{step}{OrangeRed}[hsb]{.046,0,0}
\resetcolorseries{wheel}
\begin{tikzpicture}
    \foreach \int in {1,...,10}
        \node[draw,circle,minimum size=22,fill=wheel!!+!50] 
        (\int) at (\int,0) {\int};
\end{tikzpicture}
\end{document} 

enter image description here It's just hacked together; I don't understand it well, and I'm not totally satisfied with it.

11

Note that with blue!50 you define a color that is 50% of blue. This is a very different approach to adjusting hue and saturation with a HSB color model, which I would suggest using here. With the xcolor package (or TikZ) you can define a color using the Hsb model that takes a number between 0 and 360 to define the hue (which you can easily divide through the number of steps that you want), and numbers between 0 and 1 for both saturation and brightness.

So, perhaps you can start with:

\documentclass[margin=10]{standalone}
\usepackage[rgb]{xcolor} 
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
    \foreach \hue in {0,...,6}
        \pgfmathparse{360/7*\hue}
        \definecolor{current}{Hsb}{\pgfmathresult,.5,1}
        \node[draw,circle,fill=current] (\hue) at (\hue,0) {\hue};
\end{tikzpicture}
\end{document}

enter image description here

Note that you probably need to separately load the xcolor package with rgb option to convert colours into the RGB model for output.


Approach for a wheel:

\documentclass[border=5pt]{standalone}
\usepackage[rgb]{xcolor} 
\usepackage{tikz}

\newcommand{\colorring}[4][1]{
    \def\segments{#2}
    \def\innerrad{#3}
    \def\outerrad{#4}
    \foreach \x in {1,...,\segments}
        \pgfmathparse{360/\segments*\x}
        \definecolor{current}{Hsb}{\pgfmathresult,#1,1}
        \fill[current,draw=white] (360/\segments*\x-360/\segments/2:\outerrad) 
            arc (360/\segments*\x-360/\segments/2:360/\segments*\x+360/\segments/2:\outerrad) 
            -- (360/\segments*\x+360/\segments/2:\innerrad) 
            arc (360/\segments*\x+360/\segments/2:360/\segments*\x-360/\segments/2:\innerrad) 
            -- cycle;
}

\begin{document}

\begin{tikzpicture}[scale=2, rotate=90]

\colorring{3}{0cm}{3mm}
\colorring[.9]{6}{3mm}{5mm}
\colorring[.8]{18}{5mm}{7mm}
\colorring[.7]{30}{7mm}{9mm}
\colorring[.6]{102}{9mm}{11mm}

\end{tikzpicture}

\end{document}

enter image description here

  • thanks. please use my mwe for simplicity. – voices Oct 22 at 7:15
  • Sorry, you asked for a color wheel. Your MWE does not contain such a wheel. Thus, I tried to come up with a solution with a wheel. But you can easily take my approach and use it as you like. The trick is to use the HSB color model where you can actually define the hue and the saturation as you like. – Jasper Habicht Oct 22 at 7:24
  • 2
    That's intentional. The goal isn't to draw a colour wheel. Don't get me wrong, great colour wheel, but the goal is to derive an appropriate hue palette from a colour wheel for use elsewhere (i.e., divide the wheel into n equal slices, and assign those colours the n relevant objects). The wheel ecompasses the full spectrum, evenly spaced, so naturally it's the ideal tool. Like you say, the trick is to use the model to suit our various purposes. – voices Oct 22 at 11:07
  • I added my best attempt to the question. Your update looks quite good, much easier to follow. I'm not familiar with \pgfmathresult and \pgfmathparse . I've seen them, but not really sure how to use them properly, I've always been kind of daunted by it. I guess the former is kind of like \def combined with \the\numexpr? Why ,.5,1? – voices Oct 22 at 11:48
  • \pgfmathresult stores the result of \pgfmathparse. \pgfmathparse only parses the mathematical expression, but does not output anything. If you want to output the result of the expression, you can use \pgfmathresult. Here, \pgfmathresult is used to calculate the first value (= hue) for \definecolor{current}{Hsb}{<hue>,<saturation>,<brightness>}. .5 is the value for the saturation and 1 for the brightness. – Jasper Habicht Oct 22 at 11:56
5

Aternatively, you can use the wave colormodel, which allows you to use colors by mentioning the wavelength in nanometers.

enter image description here

\documentclass[border=10pt,rgb]{standalone}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
    \foreach \N in {1,...,6}    
        \foreach \int in {1,...,\N}
            \pgfmathparse{360+int(\int*400/\N)}
            \providecolor{bar}{wave}{\pgfmathresult}
            \node[draw,circle,fill=bar!50] (\int) at (\int,-\N) {\int};
    \end{tikzpicture}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.