I would like to have a radial shading of a ring, from inner color (red) at inner radius r1 > 0 to outer color (white) at outer radius r2 > r1. But with

\filldraw[even odd rule,inner color=red,outer color=white]
(0,0) circle (2.2)
(0,0) circle (1.8);


How to choose a finite inner radius for the shading such that the full color starts at r1 = 1.8?

-

Do you mean something like the first or the second circle?

The code in which they are realized is:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\filldraw[even odd rule,inner color=red,outer color=white] (0,0) circle (2.2);
\draw(0,0) circle (1.8);
\begin{scope}[xshift=6cm]
\filldraw[even odd rule,inner color=red,outer color=red!5] (0,0) circle (1.8);
\draw(0,0) circle (2.2);
\end{scope}
\end{tikzpicture}
\end{document}


As said by percusse, the only possible approach is to define a new radial shading. Here is an example:

\documentclass{article}
\usepackage{tikz}

{rgb(0cm)=(1,1,1);
rgb(0.7cm)=(1,1,1);
rgb(0.719cm)=(1,1,1);
rgb(0.72cm)=(0.975,0,0);
rgb(0.9cm)=(1,1,1)}

\begin{document}
\begin{tikzpicture}
\draw[fill=white](0,0) circle (1.8);

\begin{scope}[xshift=6cm]
\draw(0,0) circle (1.8);
\end{scope}
\end{tikzpicture}
\end{document}


This gives you:

which I guess is your purpose. Notice that the option fill=white is not really needed, but it has been used to compare the two results.

A simple add to customize colors: the option is identical to what defined in How to shade mindmap concepts?.

The code:

\documentclass{article}
\usepackage{tikz}

\makeatletter
{rgb(0cm)=(1,1,1);
rgb(0.719cm)=(1,1,1);
color(0.72cm)=(tikz@ball);
rgb(0.9cm)=(1,1,1)}
\makeatother

\begin{document}
\begin{tikzpicture}
\filldraw[shading=ring, ring color=red] (0,0) circle (2.2cm);
\draw(0,0) circle (1.8cm);

\begin{scope}[xshift=7cm]
\filldraw[shading=ring] (0,0) circle (3) circle (2.45);
\end{scope}
\end{tikzpicture}
\end{document}


The result:

-
Dear Claudio, thanks, but neither solution is the one I am looking for. The shading should be only inside the ring between the two circles, nothing inside the inner circle, nor outside the outer circle. –  Tiong Bahru Nov 12 '12 at 16:59
Ok, now it's more clear :) I'm editing my answer. –  Claudio Fiandrino Nov 12 '12 at 17:24
Perfect. Thanks! –  Tiong Bahru Nov 12 '12 at 17:44
@TiongBahru: beware! I would advise that the ring shading is really target with the dimension you provide in your MWE. Thus in case you wonder to reduce/increase the radius you should also change a bit the position of the shading in which the color starts to be red rgb(0.72cm)=(0.975,0,0);. To change the position, just adjust (0.72cm) which is simply the distance from the circle center. –  Claudio Fiandrino Nov 12 '12 at 17:50

You need to create the region at one shot and use even odd rule or nonzero rule with some trickery for these applications. Here is one example:

\documentclass[tikz,border=5mm]{standalone}
{
color(0cm)=(transparent!0);
color(5mm)=(pgftransparent!50);
color(1cm)=(pgftransparent!100)
}

\begin{document}
\begin{tikzpicture}
\filldraw[even odd rule,red ,path fading=ringo] (0,0) circle (16mm) (0,0) circle (2cm);
\filldraw[even odd rule,blue,path fading=ringo] (0,0) circle (3mm) (0,0) circle (0.5cm);
\end{tikzpicture}
\end{document}


-
Thanks. But this example renders a ball shading. I need a color map that depends only on the radial coordinate r, not the angle. What would be a (simple) custom shading that does this job? - I couldn't find the answer in previous posts. –  Tiong Bahru Nov 12 '12 at 17:25

Here is a solution that extends Claudio Fiandrino's solution. This solution uses pgfkeys to computes automatically a new shading with different inner and outer radii. The syntax is:

(Note: The only thing I still do not understand is: why should we use the value 0.8818cm to get the correct result?)

\documentclass{standalone}
\usepackage{tikz}

\tikzset{
ring shading/.code args={from #1 at #2 to #3 at #4}{
\def\colin{#1}
\def\colout{#3}
\pgfmathsetmacro{\outer}{.8818cm}
\pgfmathsetmacro{\inner}{.8818cm*\proportion}
\pgfmathsetmacro{\innerlow}{\inner-0.01pt}
{
color(0pt)=(white);
color(\innerlow)=(white);
color(\inner)=(#1);
color(\outer)=(#3)
}
},
}

\begin{document}
\begin{tikzpicture}
(0,0) circle (2.2) circle (1.8);

(2,0) circle (0.5) circle (1.3);
\end{tikzpicture}
\end{document}


Added by Andrew Stacey - comments are lousy for posting code here's a condensed version based on investigations into where the .8818cm came from.

\tikzset{
ring shading/.code args={from #1 at #2 to #3 at #4}{
\pgfmathsetmacro{\inner}{25*#2/#4}
\pgfmathsetmacro{\innerlow}{\inner-1}
{
color(0bp)=(white);
color(\innerlow bp)=(white);
color(\inner bp)=(#1);
color(25bp)=(#3);
color(50bp)=(black)
}

(ctd) Looking at the code for the ball shading, it stops at 50bp. So we can take 50bp as a reasonable guess at the size of the rectangle that PGF will try to shade. It would also seem (from looking at the ball shading) that 25bp is the key length for shading a circle: that is where the edge of the circle will lie in the shading. Now we see where the .8818cm comes from! .8818cm is almost 25pt so \pgfmathparse{.8818cm} results in about 25 (as pgfmath converts lengths to pts). –  Loop Space Nov 13 '12 at 18:38