[Tex/LaTex] How to design a 3D donut pie chart with pgf-plot

chartspgfplotsstatisticstikz-pgf

It seems that pgfplots users don't like pie charts but sometimes we can't go without (for some reasons). So I was wondering if there was a way to make what is called a donut chart.

For example one like this:

Image of an donut

Best Answer

Like T. Tantau and Mark S. Everitt, I think it's a bad thing to do this. I don't understand if you want to use pgfplots or pgf plots ? It's not exactly the same things. The code would be better if yshift for the shadow is calculated in function of the height of the picture.

Update 2

Some corrections, complete and clean the code.

enter image description here

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{fadings}

\begin{document}
\begin{tikzpicture}[fading style/.style={preaction={fill=#1,opacity=.8,
                   path fading=circle with fuzzy edge 20 percent}}]

  \begin{scope}[xscale=5,yscale=3]
    \path[fading style=black,transform canvas={yshift=-40pt}] (0,0) circle (1cm);         
    \fill[gray](0,0) circle (0.5cm);  
    \path[fading style=white,transform canvas={yshift=-16mm}] (0,0) circle (0.65cm);    
    \draw[yshift=-3mm](0,0) circle (0.5cm); 

    \shadedraw[top color=green!20!gray,,bottom color=green!5!black,draw=black,very thin]  
        (90:0.5cm)--++(0,-3mm) arc(90:-5:0.5cm)--++(0,3mm)  arc(-5:90:0.5cm)--cycle;      
    \shadedraw[top color=orange!20!gray,bottom color=orange!5!black,draw=black,very thin]   
        (-105:0.5cm)--++(0,-3mm) arc(-105:-225 :0.5cm)--++(0,3mm)  arc(-225:-105:0.5cm)--cycle;   
    \shadedraw[top color=blue!50!white,,bottom color=blue!5!black,draw=black,very thin]   
        (135 :0.5cm)--++(0,-3mm) arc(135:90:0.5cm)--++(0,3mm)  arc(90:135:0.5cm)--cycle;  

    \begin{scope}[draw=black,thin]
       \fill[green!20!gray](90 :0.5cm)--(90:1cm) arc(90:-5:1cm)--(-5:0.5cm) arc(-5:90 :0.5cm);     
       \fill[white!20!gray](-5 :0.5cm)--(-5:1cm) arc(-5:-105 :1cm)--(-105:0.5cm) arc(-105:-5:0.5cm);        
       \fill[orange!20!gray](-105:0.5cm)--(-105:1cm) arc(-105:-225 :1cm)--(-225:0.5cm) arc(-225:-105:0.5cm);
       \fill[blue!50!white](135:0.5cm)--(135 :1cm) arc(135:90:1cm)--(90:0.5cm) arc(90:135:0.5cm);
    \end{scope}
    \draw[thin,black](0,0) circle (0.5cm);   

    \shadedraw[bottom color=orange!20!gray,top color=orange!5!black,draw=black,very thin]   
    (-180:1cm) --++(0,-3mm) arc (-180:-105 :1cm) -- ++(0,3mm)  arc (-105 :-180  :1cm) -- cycle;  
    \shadedraw[bottom color=white!20!gray,top color=white!5!black,draw=black,very thin]   
    (-105:1cm) --++(0,-3mm) arc (-105:0 :1cm) -- ++(0,3mm)  arc (0 :-105  :1cm) -- cycle;  

      \draw[very thin] (90:0.5cm) -- (90:1cm)
            (-5:0.5cm) -- (-5:1cm)
            (-105:0.5cm) -- (-105:1cm)
            (135:0.5cm) -- (135 :1cm)
            (0,0) circle (1cm)
            (90:0.5cm)  arc (90 :135:0.5cm);

    \coordinate (left border) at (1.5cm,0cm); 
    \coordinate (right border) at (-1.5cm,0cm); 
    \coordinate (l1) at (43.5:0.75 cm);
    \coordinate (l2) at (-55:0.75 cm); 
    \coordinate (l3) at (117.5:0.75 cm);
    \coordinate (l4) at (-160:0.75 cm);

    \begin{scope}[lab/.style={gray!50!black,thick,draw}]
        \fill[lab] (l1) circle(.4mm) -- (l1-| left border) node[anchor=south east] {Corporate}
                                                           node[anchor=north east] {26\%};         
       \fill[lab] (l2) circle(.4mm) -- (l2-| left border)  node[anchor=south east] {Plastique}
                                                           node[anchor=north east] {28\%}; 
       \fill[lab] (l3) circle(.4mm) -- (l3-| right border) node[anchor=south west] {Rhodia}
                                                           node[anchor=north west] {12.5\%};         
       \fill[lab] (l4) circle(.4mm) -- (l4-| right border) node[anchor=south west] {Chimique}
                                                           node[anchor=north west] {43.5\%}; 
    \end{scope}
   \end{scope}  
\end{tikzpicture}    
\end{document}        

Attempt to automate version 4

macro \piechartthreed

Two arguments #1 for the options #2 list of angles and colors (a1/col1,a2/col2,etc...)

Options scale scale the pie chart, mix color used to color the sector, background color color for the background, name used to name the point at the "center" of each sector.

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{fadings}

\pgfkeys{%
/piechartthreed/.cd,
scale/.code                =  {\def\piechartthreedscale{#1}},
mix color/.code            =  {\def\piechartthreedmixcolor{#1}},
background color/.code     =  {\def\piechartthreedbackcolor{#1}},
name/.code                 =  {\def\piechartthreedname{#1}}}

 \newcommand\piechartthreed[2][]{% 
   \pgfkeys{/piechartthreed/.cd,
     scale            = 1,
     mix color        = gray,
     background color = white,
     name             = pc} 
  \pgfqkeys{/piechartthreed}{#1}
  \begin{scope}[scale=\piechartthreedscale] 
  \begin{scope}[xscale=5,yscale=3] 
     \path[preaction={fill=black,opacity=.8,
         path fading=circle with fuzzy edge 20 percent,
         transform canvas={yshift=-15mm*\piechartthreedscale}}] (0,0) circle (1cm);
    \fill[gray](0,0) circle (0.5cm);  
     \path[preaction={fill=\piechartthreedbackcolor,opacity=.8,
          path fading=circle with fuzzy edge 20 percent,
          transform canvas={yshift=-10mm*\piechartthreedscale}}] (0,0) circle (0.5cm);
     \pgfmathsetmacro\totan{0} 
     \global\let\totan\totan 
     \pgfmathsetmacro\bottoman{180} \global\let\bottoman\bottoman 
     \pgfmathsetmacro\toptoman{0}   \global\let\toptoman\toptoman 
     \begin{scope}[draw=black,thin]
     \foreach \an/\col [count=\xi] in {#2}{%
     \def\space{ } 
        \coordinate (\piechartthreedname\space\xi) at (\totan+\an/2:0.75cm); 
        \ifdim 180pt>\totan pt 
         \ifdim 0pt=\toptoman pt
            \shadedraw[left color=\col!20!\piechartthreedmixcolor,
                       right color=\col!5!\piechartthreedmixcolor,
                       draw=black,very thin] (0:.5cm) -- ++(0,-3mm) arc (0:\totan+\an:.5cm) 
                                                       -- ++(0,3mm)  arc (\totan+\an:0:.5cm);
            \pgfmathsetmacro\toptoman{180} 
            \global\let\toptoman\toptoman         
            \else
            \shadedraw[left color=\col!20!\piechartthreedmixcolor,
                       right color=\col!5!\piechartthreedmixcolor,
                       draw=black,very thin](\totan:.5cm)-- ++(0,-3mm) arc(\totan:\totan+\an:.5cm)
                                                        -- ++(0,3mm)  arc(\totan+\an:\totan:.5cm); 
          \fi
        \fi   
        \fill[\col!20!gray,draw=black] (\totan:0.5cm)--(\totan:1cm)  arc(\totan:\totan+\an:1cm)
                                     --(\totan+\an:0.5cm) arc(\totan+\an:\totan :0.5cm);     
       \pgfmathsetmacro\finan{\totan+\an}
       \ifdim 180pt<\finan pt 
         \ifdim 180pt=\bottoman pt
            \shadedraw[left color=\col!20!\piechartthreedmixcolor,
                       right color=\col!5!\piechartthreedmixcolor,
                       draw=black,very thin] (180:1cm) -- ++(0,-3mm) arc (180:\totan+\an:1cm) 
                                                       -- ++(0,3mm)  arc (\totan+\an:180:1cm);
            \pgfmathsetmacro\bottoman{0}
            \global\let\bottoman\bottoman
            \else
            \shadedraw[left color=\col!20!\piechartthreedmixcolor,
                       right color=\col!5!\piechartthreedmixcolor,
                       draw=black,very thin](\totan:1cm)-- ++(0,-3mm) arc(\totan:\totan+\an:1cm)
                                                        -- ++(0,3mm)  arc(\totan+\an:\totan:1cm); 
          \fi
        \fi
        \pgfmathsetmacro\totan{\totan+\an}  \global\let\totan\totan 
       } 
    \end{scope}
    \draw[thin,black](0,0) circle (0.5cm);
   \end{scope}  
\end{scope}
}

\begin{document} 
 \pagecolor{orange!50}
 \begin{tikzpicture}
   \piechartthreed[scale=0.8,
                   background color=orange!50,
                   mix color= darkgray]
                   {40/green,60/blue,90/red,50/orange,120/yellow}
   \foreach \i in {1,...,5} { \fill (pc \i) circle (.5mm);}
   \draw[darkgray] (pc 1)  -- ++(4,0) coordinate (s1) node[anchor=south east] {Sector 1}
                                                      node[anchor=north east] {11\%};
   \draw[darkgray] (pc 5)  -- (pc 5 -| s1) node[anchor=south east] {Sector 5}
                                                      node[anchor=north east] {33\%}; 
   \draw[darkgray] (pc 2)  -- ++(1,1) coordinate (s2) -- (s2 -| s1) node[anchor=south east] {Sector 2}
                                                      node[anchor=north east] {17\%}; 
   \draw[darkgray] (pc 3)  -- ++(-4,0) coordinate (s3) node[anchor=south west] {Sector 3}
                                                      node[anchor=north west] {14\%};
   \draw[darkgray] (pc 4)  -- ++(-1,-1) coordinate (s4) --(s4 -| s3) node[anchor=south west] {Sector 4}
                                                      node[anchor=north west] {25\%};
 \end{tikzpicture}

\end{document}

enter image description here

todo

Clean the code and add some options.

Related Question