4

I noticed first that yellow!50!green did not produce the same color as green!50!yellow. Then I tried more systematically:

\begin{tikzpicture}
\foreach\y in {0,10,...,100} {
\fill[green!\y!yellow] (.1*\y,0) rectangle ++(1,1);
\fill[yellow!\y!green] (.1*\y,2) rectangle ++(1,1);
}
\end{tikzpicture}

This is what I get: mix green and yellow

What exactly is going on there?

Ingmar
  • 6,690
  • 5
  • 26
  • 47
  • 7
    Load the package xcolor before tikz with an option other than natural, say rgb or cmyk depending on your document. Then the colors will mix properly. (Green comes from rgb, yellow from cmyk.) – Qrrbrbirlbel Jul 08 '23 at 02:01
  • @Qrrbrbirlbel In light of the existing answer, could you elaborate a bit more? – Teepeemm Jul 08 '23 at 15:27
  • @Teepeemm I'm working on something. I'm not an expert on colors and color models and color conversion but I have solutions. (The easiest one would be to chose one or the other …) – Qrrbrbirlbel Jul 08 '23 at 17:48
  • Or not. Muzimuzhi has basically posted what I had worked on. Let me leave some links to related Q&A: 1, 2 – Qrrbrbirlbel Jul 08 '23 at 21:27
  • You mix green!y with yellow, and yellow!y with green. It‘s not symmetrical by syntax. – MS-SPO Jul 09 '23 at 10:37

1 Answers1

4
  1. xcolor uses color model natural by default.
    (See xcolor package doc, Table 1: "Package options".)
  2. In natural color model, green is in rgb model and yellor is in cmyk model.
    (Can only be checked clearly from source code (1 and 2), but the Figure 4: "Target color model" in package doc tells the difference a bit.)
  3. In a color mix expression like <name1>!<pct>!<name2> (<pct> is short for percent), if <name1> and <name2> are in different color models, in normal case when 0 < <pct> < 100 the resulting color has the same model with <name1>.
    (See xcolor package doc, sec. 2.3.2 "Meaning of standard color expressions", the note paragraph after numbered list.)
  4. Specifically, if <pct> is 0, <name2> is returned, without model transformation. In this case, the resulting color has the same model with <name2>, not <name1>.
    (ditto)

To set or change current color model, one of the following ways can be used:

  • Use \PassOptionsToPackage{<model>}{xcolor} before xcolor is loaded.
  • Use model name as package option, for example \usepackage[rgb]{xcolor}.
  • Use \selectcolormodel{<model>} after xcolor is loaded.
\documentclass{article}
\usepackage{tikz}

\newcommand{\printColorSpec}[1]{% \textcolor{#1}{\rule{1em}{1em}} \extractcolorspec{#1}{\temp}% \makebox[4cm][l]{\detokenize{"#1"}} -> \detokenize\expandafter{\temp}\par }

\newcommand\testColorMixing[1]{% \noindent Color Model: \texttt{#1}\ \selectcolormodel{#1}% \begin{tikzpicture} \foreach \y in {0,10,...,100} { \fill[green!\y!yellow] (.1\y,0) rectangle ++(1,1); \fill[yellow!\y!green] (.1\y,1.1) rectangle ++(1,1); } \end{tikzpicture} \par }

\parindent=0pt

\begin{document}

Color Model: \texttt{natural} \selectcolormodel{natural}

\ttfamily \printColorSpec{green} \printColorSpec{yellow} \medskip\hrule\par\medskip

\printColorSpec{green!0!yellow} \printColorSpec{green!10!yellow} \printColorSpec{green!20!yellow} \hspace*{.3em}\vdots\par \printColorSpec{green!90!yellow} \printColorSpec{green!100!yellow} \medskip\hrule\par\medskip

\printColorSpec{yellow!0!green} \printColorSpec{yellow!10!green} \printColorSpec{yellow!20!green} \hspace*{.3em}\vdots\par \printColorSpec{yellow!90!green} \printColorSpec{yellow!100!green} \medskip\hrule\par\medskip

\testColorMixing{natural} % default \testColorMixing{rgb} \testColorMixing{cmyk} \end{document}

enter image description here

muzimuzhi Z
  • 26,474