Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to gradually shade a rectangle in a way that e.g. bottom edge is red and left edge is blue.

\fill[left color=blue,bottom color=red] (0,0) rectangle (2,2);

Therefore colour should be changing by azimuth, like colour wheel centred in bottom left angle. Is that possible to do?

Thanks.

share|improve this question
    
What should happen at the bottom left? How can the whole of the left be blue and the whole of the bottom be red? What have you tried? Did you try just clipping a colour wheel shading to a rectangle? Please give a Minimum Working Example. –  cfr Aug 25 at 18:42

3 Answers 3

up vote 5 down vote accepted

I don't enjoy Postscript, it makes my head hurt. Anyway here is another linear interpolated shading. You can use it in TikZ pictures too.

\documentclass[]{article}
\usepackage{tikz}
\pgfdeclarefunctionalshading[vcol,hcol]{azimuth}{\pgfpointorigin}%
{\pgfpoint{4cm}{4cm}}{\pgfshadecolortorgb{vcol}{\mycola}\pgfshadecolortorgb{hcol}{\mycolb}}{
atan 90 div dup dup 
\mycolablue \mycolbblue sub exch mul \mycolablue exch sub 3 1 roll
\mycolagreen \mycolbgreen sub mul \mycolagreen exch sub exch 
\mycolared \mycolbred sub mul \mycolared exch sub 3 1 roll exch 
}

\begin{document}
\colorlet{vcol}{black}
\colorlet{hcol}{yellow}
\pgfuseshading{azimuth}
%
\colorlet{vcol}{red}
\colorlet{hcol}{green}
\pgfuseshading{azimuth} % Ow, colorblind highness
%
\colorlet{vcol}{white}
\colorlet{hcol}{blue}
\pgfuseshading{azimuth}
\end{document}

enter image description here

An example of using this shading in TikZ pictures;

\documentclass[tikz]{standalone}

\tikzset{vcol/.code={\colorlet{vcol}{#1}},hcol/.code={\colorlet{hcol}{#1}},vcol=red,hcol=blue}
\pgfdeclarefunctionalshading[vcol,hcol]{azimuth}{\pgfpointorigin}%
{\pgfpoint{50bp}{50bp}}%
{%
\pgfshadecolortorgb{vcol}{\mycola}%
\pgfshadecolortorgb{hcol}{\mycolb}
}{%
atan 90 div dup dup 
\mycolablue \mycolbblue sub mul \mycolablue exch sub 3 1 roll
\mycolagreen \mycolbgreen sub mul \mycolagreen exch sub exch 
\mycolared \mycolbred sub mul \mycolared exch sub 3 1 roll exch 
}

\begin{document}
\begin{tikzpicture}[shading=azimuth]
% Start modern art
\shade[vcol=yellow,hcol=black] (0,0) rectangle (5,3);
\shade[vcol=red!50!yellow,hcol=blue!80!purple!70!black] (-3,0) circle (1.5);
\shade[vcol=orange,hcol=green!50!blue] (-3,0) ++ (150:3.5) -- ++(150:1cm) 
                                       arc (150:90:4.5cm) coordinate(a)
                                       --++(-40:3cm)|-++(0,-2cm)
                                       arc (20:110:3cm)--cycle;
\end{tikzpicture}
\end{document}

enter image description here

Notice that, in the complicated paths, there is some serious clipping, scaling and translation going on. So this would best work on squares. Also this is very likely to upset your printer since many of them will have an incompatible PS interpreter. Test those pages first. And yes, I'm colorblind so nevermind the examples.

share|improve this answer
    
I don't quite get it. Can I fill a square with azumuth shading? –  Pygmalion Aug 26 at 7:04
    
@Pygmalion My bad. I'll add an example later when I have time. The answer is yes. –  percusse Aug 26 at 7:20
    
@Pygmalion Added more TikZ syntax examples. –  percusse Aug 26 at 18:34
    
Great! This solves my other question too, so I will delete it! –  Pygmalion Aug 26 at 18:52
    
I have chosen this solution, because it is (a) fast and (b) easily adaptable to various problems. I don't understand a single line of code, though :) –  Pygmalion Aug 31 at 13:03

Another approach, using PGFPlots to draw a surface plot:

\documentclass{article}

\usepackage{pgfplots} 

\begin{document} 
\begin{tikzpicture}
\begin{axis}[
    view={0}{90},
    hide axis,
    axis equal image,
    xmax=pi, ymax=pi,
    samples y=6,
    colormap={redblue}{color(0cm)=(red); color(1cm)=(blue)}
]
\addplot3 [
    surf, shader=interp,
    domain=0:90,
    y domain=0:2*pi,
    data cs=polar
] (x,y,x);
\end{axis}
\end{tikzpicture}
\end{document}

This makes it possible to specify other color gradients. For instance, you can get a gradient that starts at red, goes to yellow at 30 degrees, and then to blue:

\documentclass{article}

\usepackage{pgfplots} 

\begin{document} 
\begin{tikzpicture}
\begin{axis}[
    view={0}{90},
    hide axis,
    axis equal image,
    xmax=pi, ymax=pi,
    samples y=6, samples=60,
    colormap={redyellowblue}{color(0cm)=(red); color(0.33333cm)=(yellow); color(1cm)=(blue)}
]
\addplot3 [
    surf, shader=interp,
    domain=0:90,
    y domain=0:2*pi,
    data cs=polar
] (x,y,x);
\end{axis}
\end{tikzpicture}
\end{document}
share|improve this answer
    
Smart one! Like it –  JLDiaz Aug 25 at 19:10
    
Wow! This is nice. –  Pygmalion Aug 25 at 19:34
    
I actually need this shading as a part of one pgfplot. Is it possible to do that without starting pgfplot within pgfplot? –  Pygmalion Aug 25 at 19:36
    
@Pygmalion: That depends on your use case. Could you start a new question with an example? –  Jake Aug 25 at 20:12
    
I did as you proposed: tex.stackexchange.com/questions/197910/… –  Pygmalion Aug 25 at 22:02

A possible way: fake the gradient by drawing lots of thin triangles in solid colors which smoothly change their color from red to blue. The resulting "disc" can be clipped to a rectangle, as the following example shows:

\begin{tikzpicture}
\path[clip] (0,0) rectangle (1,0.7);
\foreach \i in {0,0.5,...,90} {
 \pgfmathsetmacro{\shade}{100/(90-0)*\i}
  \fill[draw=none,blue!\shade!red] (0:0) -- (\i:1.4) -- (\i+1:1.4) -- cycle;
}
\draw (0,0) rectangle (1,0.7);
\end{tikzpicture}

Result

share|improve this answer
    
Nice solution. :) –  Pygmalion Aug 25 at 19:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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