6

In an earlier question I learned how to make a diagonal shading on a left-hand page which was reflected on the right-hand page. This has been working fine thanks to Ignasi and others.

But for the print version it has to be CMYK, not RGB. According to this question, CMYK is not possible with current TikZ pgf drivers, whereas pgfplots can do shadings which work with its own CMYK drivers.

I can't figure out what pgfplots commands I need to produce the example below. The examples in the pgfplots documentation are all fabulously more complex than I need, and are (understandably) aimed at plotting diagrams with axes, where the shading is used to display features of the data. Is it possible to use pgfplots just to create a diagonally-shaded area on its own (and reflect it)?

Example of two-page spread using reflected diagonal shading

  • The xcolor package (used by tikz) supports different color models, but playing with \selectcolormodel and \substitutecolormodel did not change the PDF from using /Shading << /Sh << /ShadingType 2 /ColorSpace /DeviceRGB. You might try Acrobat Professional (preferably without buying it). – John Kormylo Aug 27 '17 at 20:50
10

Yes, it is possible.

Side note: While the following produces interesting pictures and answers the question, I hope this really addresses what you intent to do with the result... a pgfplots axes needs some fine tuning before it can be integrated into a bigger tikzpicture (due to its coordinate rescaling). If you need assistence in this direction, you may need to consider section 4.26 TikZ Interoperability of the pgfplots manual. The correct solution would be to actually implement CMYK shadings in PGF... End of side note.

The idea is to assign a coordinate system (as you would probably do in tikz as well) and assign colors to each coordinate. Then we need to connect the edges and interpolate. Interpolation requires a geometry, and I chose to use triangles.

In a first draft, this would be

\documentclass{standalone}

\usepackage[cmyk]{xcolor}
\usepackage{pgfplots}

\pgfplotsset{compat=1.15}

\definecolor{custdark}{cmyk}{0,0.3,1,0.27}
\definecolor{custlight}{cmyk}{0,0.05,0.55,0.05}

\begin{document}

\begin{tikzpicture}

    \begin{axis}[
        x=5cm,y=5cm,
    ]
    \addplot[patch,mesh/color input=explicit,shader=faceted interp] 
    table[meta=cdata] {
        x y cdata
        % first triangle: upper left corner
        0 0 color=custlight
        1 1 color=custlight
        0 1 color=custdark

        % second triangle:left side, lower right corner
        0 0 color=custlight
        1 0 color=custdark
        1 1 color=custlight

        % third triangle right side, lower left corner
        1 0 color=custdark
        2 0 color=custlight
        1 1 color=custlight

        % 4th triangle upper right corner
        2 0 color=custlight
        2 1 color=custdark
        1 1 color=custlight
    };
    \end{axis}
\end{tikzpicture}


\end{document}

enter image description here

The final version would hide the axis and show only a part, namely the one in the x range [0.5,1.5]:

\documentclass{standalone}

\usepackage[cmyk]{xcolor}
\usepackage{pgfplots}

\pgfplotsset{compat=1.15}

\definecolor{custdark}{cmyk}{0,0.3,1,0.27}
\definecolor{custlight}{cmyk}{0,0.05,0.55,0.05}

\begin{document}

\begin{tikzpicture}

    \begin{axis}[
        x=5cm,y=5cm,xmin=0.5,xmax=1.5,hide axis]
    \addplot[patch,mesh/color input=explicit,shader=interp] 
    table[meta=cdata] {
        x y cdata
        % first triangle: upper left corner
        0 0 color=custlight
        1 1 color=custlight
        0 1 color=custdark

        % second triangle:left side, lower right corner
        0 0 color=custlight
        1 0 color=custdark
        1 1 color=custlight

        % third triangle right side, lower left corner
        1 0 color=custdark
        2 0 color=custlight
        1 1 color=custlight

        % 4th triangle upper right corner
        2 0 color=custlight
        2 1 color=custdark
        1 1 color=custlight
    };
    \end{axis}
\end{tikzpicture}


\end{document}

enter image description here


The following is a variation which adds more complexity.


It seems that your shading stops somewhere in the lower middle, i.e. there is the same color. This can also be archieved by means of pgfplots if we resort to colormaps. A colormap is just a rectangular shading, but prepared for a special use-case (see below).

Here, I suggest the following colormap:

\documentclass{standalone}

\usepackage[cmyk]{xcolor}
\usepackage{pgfplots}

\pgfplotsset{compat=1.15}

\definecolor{custdark}{cmyk}{0,0.3,1,0.27}
\definecolor{custlight}{cmyk}{0,0.05,0.55,0.05}

\begin{document}

    \pgfplotsset{
        colormap={customtransition}{
            color(0)=(custlight)
            color(800)=(custdark)
            color(1000)=(custdark)
        },
    }
    \pgfplotscolorbardrawstandalone[colorbar horizontal]
\end{document}

enter image description here

It interpolates linearly between 0 and 800 and keeps the same color between 800 and 1000 .

We can define the colors associated with the corners of our triangles by means of this colormap as well which results in the following:

\documentclass{standalone}

\usepackage[cmyk]{xcolor}
\usepackage{pgfplots}

\pgfplotsset{compat=1.15}

\definecolor{custdark}{cmyk}{0,0.3,1,0.27}
\definecolor{custlight}{cmyk}{0,0.05,0.55,0.05}

\begin{document}

\begin{tikzpicture}

    \begin{axis}[x=5cm,y=5cm,
        xmin=0.5,xmax=1.5,hide axis,
    ]
    \addplot[patch,
        point meta=explicit,
        mesh/color input=colormap,
        shader=interp,
        colormap={customtransition}{
            color(0)=(custlight)
            color(800)=(custdark)
            color(1000)=(custdark)
        },
    ]
    table[meta=cdata] {
        x y cdata
        % first triangle: upper left corner
        0 0 0
        1 1 0
        0 1 1

        % second triangle:left side, lower right corner
        0 0 0
        1 0 1
        1 1 0

        % third triangle right side, lower left corner
        1 0 1
        2 0 0
        1 1 0

        % 4th triangle upper right corner
        2 0 0
        2 1 1
        1 1 0
    };
    \end{axis}
\end{tikzpicture}

\end{document}

enter image description here

Now, the "cdata" is a reference to a color in the colormap. Interpolation is carried out in the "cdata", i.e. in the number. The interpolated number refers to a different color in the colormap. Example: the middle of cdata "0" and "1" is "0.5". And this refers to color 500 in the colormap. This allows a different (actually more powerful) control over the shading. Note that the mapping is scaled automatically to [0,1000], i.e. the minimal cdata value "0" is mapped to 0 in the colormap and the maximal cdata value "1" is mapped to 1000 in the colormap.

  • Very nice! As I'm unable to transfer your workarounds, please, could you also give an example, how to let tikz shade text using cmyk? (for Details see: tex.stackexchange.com/a/192528/112503) Thank you very much! And - in regard of your comment (tex.stackexchange.com/questions/137228/… - how about implementing native CMYK support into tikz driver? ;-) – lAtExFaN Sep 27 '17 at 9:06
  • I feared that the solution cannot be easily transfered to the actual use-case... and I do not know how to transfer them here without implementing a generic tikz variant. Regarding the state of the feature request to implement native CMYK shadings: it would be great to do it, yes. However, I do not have the time available to do it for the foreseeable future. – Christian Feuersänger Sep 27 '17 at 20:42
  • @ChristianFeuersänger, is this still the best technique for CMYK shading in tikz? I need to clip a horizontal gradient to a path. – David Purton Jun 24 '18 at 13:31
  • I am unaware of other solutions, but I haven't pursued the issue for some time – Christian Feuersänger Jun 25 '18 at 17:56

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.