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:
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It only takes a minute to sign up.
Sign up to join this communityIt 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:
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.
\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}
todo
Clean the code and add some options.
mix rate low
and mix rate high
and replace the values 20/5 in the code with \piechartthreedmixratehigh
/\piechartthreedmixratelow
. Then setting the high/low mix rates to 80/60 makes nice and shiny colors. You also need to replace the remaining occurence of gray
in \col!20!gray
with \piechartthreedmixcolor
run it with xelatex
or latex->dvips->ps2pdf
\documentclass{article}
\usepackage[dvipsnames,svgnames]{pstricks}
\usepackage{pst-solides3d}
\begin{document}
\begin{pspicture}(-3.5,-1.5)(3.5,1.5)
\psset[pst-solides3d]{viewpoint=50 20 20 rtp2xyz,
Decran=20}
\psSolid[object=anneau,h=1,R=8,r=6,ngrid=90,grid=false,
fcol= 0 1 19 { (Red) } for
20 1 59 { (LimeGreen) } for
60 1 179 { (Blue) } for
180 1 299 { (Sepia) } for
300 1 359 { (BrickRed) } for
](0,0,0)
\end{pspicture}
\end{document}
or with grid lines:
\documentclass{article}
\usepackage[dvipsnames,svgnames]{pstricks}
\usepackage{pst-solides3d}
\begin{document}
\begin{pspicture}(-3.5,-1.5)(3.5,1.5)
\psset[pst-solides3d]{viewpoint=50 20 20 rtp2xyz,
Decran=20}
\psSolid[object=anneau,h=1,R=8,r=6,ngrid=90,linewidth=0.1pt,
fcol= 0 1 19 { (Red) } for
20 1 59 { (LimeGreen) } for
60 1 179 { (Blue) } for
180 1 299 { (Sepia) } for
300 1 359 { (BrickRed) } for
](0,0,0)
\end{pspicture}
\end{document}
Here is a first version. So far you can only define the angles of the individual sectors. In the center of each sector there is a node n(sector number) which you can use for labeling.
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc}
\global\edef\lastangle{0}
\newcounter{sectornumber}
\newcommand{\ring}[1]{% angles
\setcounter{sectornumber}{1}
\foreach \x in {#1}
{ \pgfmathsetmacro{\na}{\lastangle+\x}
\fill[red,draw=black] (\lastangle:3) arc (\lastangle:\na:3) -- ++(0,0,0.5) arc (\na:\lastangle:3) -- cycle;
\fill[blue,draw=black] (\lastangle:4) arc (\lastangle:\na:4) -- ++(0,0,0.5) arc (\na:\lastangle:4) -- cycle;
\global\edef\lastangle{\na}
}
\global\edef\lastangle{0}
\foreach \x in {#1}
{ \pgfmathsetmacro{\na}{\lastangle+\x}
\fill[green,draw=black] (0,0,0.5) ++(\lastangle:3) arc (\lastangle:\na:3) -- ++(\na:1) arc (\na:\lastangle:4) -- cycle;
\node (n\thesectornumber) at ($(0,0,0.5)+(\lastangle+\x/2:3.5)$) {};
\stepcounter{sectornumber}
\global\edef\lastangle{\na}
}
}
\begin{document}
\begin{tikzpicture}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
\ring{10,20,30,40,50,60,70,80}
\draw[thick] (n1) -- ++(5:2) node[above right] {Bla 1};
\draw[thick] (n3) -- ++(45:2) node[above] {Bla 2};
\draw[thick] (n6) -- ++(180:2) node[left] {Bla 3};
\draw[thick] (n8) -- ++(-45:2) node[right] {Bla 4};
\end{tikzpicture}
\end{document}
Edit 1: a revised version, with choosable colors and shaded edges. It only works for quite flat rings:
\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc,shapes,shadows}
\global\edef\lastangle{0}
\newcounter{sectornumber}
\newcommand{\ring}[4]{% angles&colors, inner, outer radius, height
\begin{scope}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
\global\edef\lastangle{0}
\setcounter{sectornumber}{1}
\foreach \x/\ringcolor in {#1}
{ \pgfmathsetmacro{\na}{\lastangle+\x*3.6}
\colorlet{darkercolor}{\ringcolor!60!black}
\colorlet{darkestcolor}{\ringcolor!20!black}
\shadedraw[top color=darkercolor,bottom color=darkestcolor,draw=darkercolor] (\lastangle:#2) arc (\lastangle:\na:#2) -- ++(0,0,#4) arc (\na:\lastangle:#2) -- cycle;
\shadedraw[top color=darkercolor,bottom color=darkestcolor,draw=darkercolor] (\lastangle:#3) arc (\lastangle:\na:#3) -- ++(0,0,#4) arc (\na:\lastangle:#3) -- cycle;
\global\edef\lastangle{\na}
}
\global\edef\lastangle{0}
\foreach \x/\ringcolor in {#1}
{ \pgfmathsetmacro{\na}{\lastangle+\x*3.6}
\colorlet{darkercolor}{\ringcolor!60!black}
\colorlet{darkestcolor}{\ringcolor!20!black}
\fill[\ringcolor,draw=darkercolor] (0,0,#4) ++(\lastangle:#2) arc (\lastangle:\na:#2) -- ++(\na:#3-#2) arc (\na:\lastangle:#3) -- cycle;
\pgfmathsetmacro{\nodepos}{(#3+#2)*0.5}
\node (n\thesectornumber) at ($(0,0,#4)+(\lastangle+\x*1.8:\nodepos)$) {};
\stepcounter{sectornumber}
\global\edef\lastangle{\na}
}
\end{scope}
}
\begin{document}
\begin{tikzpicture}
\ring{5/red!80!gray,15/blue!80!gray,15/yellow!80!gray,25/green!80!gray,10/orange!80!gray,10/violet!80!gray,5/brown!80!gray,15/cyan!80!gray}{3}{4}{0.5}
\foreach \x/\label in {1/Kill Bill,2/The Godfather,3/Garden State,4/Sin City,5/Fight Club,6/Star Trek VI,7/Terminator 2,8/Gran Torino}
{ \draw[thick] (n\x) -- ++(0,0.5) node[fill=white,draw,rounded rectangle,inner sep=2pt,thin,fill opacity=0.7,text opacity=1] {\tiny\label};
}
\end{tikzpicture}
\begin{tikzpicture}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
\ring{5/red!80!gray,15/blue!80!gray,15/yellow!80!gray,25/green!80!gray,10/orange!80!gray,10/violet!80!gray,5/brown!80!gray,15/cyan!80!gray}{2}{4}{2}
\foreach \x/\label in {1/Kill Bill,2/The Godfather,3/Garden State,4/Sin City,5/Fight Club,6/Star Trek VI,7/Terminator 2,8/Gran Torino}
{ \draw[thick] (n\x) -- ++(0.5,0.5) node[fill=white,draw,rounded rectangle,inner sep=2pt,thin,fill opacity=0.7,text opacity=1] {\tiny\label};
}
\end{tikzpicture}
\end{document}