4

I was able to create a pie chart based on the answer in How to draw Bar & Pie Chart.

I realized my document is printed in grayscale and learned about patterns (Where is the pattern list gallery for pgfplots?) that can be applied to a plot object. In bar charts I can easily provide one using \addplot based from my question before in Add background pattern to tikzpicture vertical bars.

How can I do this with a pie chart with each slice having a unique pattern background?

Here is the code I used with flat colors:

\documentclass{standalone}
\usepackage{tikz,pgf} 

\definecolor{rosso}{RGB}{220,57,18}
\definecolor{giallo}{RGB}{255,153,0}
\definecolor{blu}{RGB}{102,140,217}
\definecolor{verde}{RGB}{16,150,24}
\definecolor{viola}{RGB}{153,0,153}

\makeatletter

\tikzstyle{chart}=[
    legend label/.style={font={\scriptsize},anchor=west,align=left},
    legend box/.style={rectangle, draw, minimum size=5pt},
    axis/.style={black,semithick,->},
    axis label/.style={anchor=east,font={\tiny}},
]

\tikzstyle{bar chart}=[
    chart,
    bar width/.code={
        \pgfmathparse{##1/2}
        \global\let\bar@w\pgfmathresult
    },
    bar/.style={very thick, draw=white},
    bar label/.style={font={\bf\small},anchor=north},
    bar value/.style={font={\footnotesize}},
    bar width=.75,
]

\tikzstyle{pie chart}=[
    chart,
    slice/.style={line cap=round, line join=round, very thick,draw=white},
    pie title/.style={font={\bf}},
    slice type/.style 2 args={
        ##1/.style={fill=##2},
        values of ##1/.style={}
    }
]

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}


\newcommand{\pie}[3][]{
    \begin{scope}[#1]
    \pgfmathsetmacro{\curA}{90}
    \pgfmathsetmacro{\r}{1}
    \def\c{(0,0)}
    \node[pie title] at (90:1.3) {#2};
    \foreach \v/\s in{#3}{
        \pgfmathsetmacro{\deltaA}{\v/100*360}
        \pgfmathsetmacro{\nextA}{\curA + \deltaA}
        \pgfmathsetmacro{\midA}{(\curA+\nextA)/2}

        \path[slice,\s] \c
            -- +(\curA:\r)
            arc (\curA:\nextA:\r)
            -- cycle;
        \pgfmathsetmacro{\d}{max((\deltaA * -(.5/50) + 1) , .5)}

        \begin{pgfonlayer}{foreground}
        \path \c -- node[pos=\d,pie values,values of \s]{$\v\%$} +(\midA:\r);
        \end{pgfonlayer}

        \global\let\curA\nextA
    }
    \end{scope}
}

\newcommand{\legend}[2][]{
    \begin{scope}[#1]
    \path
        \foreach \n/\s in {#2}
            {
                  ++(0,-10pt) node[\s,legend box] {} +(5pt,0) node[legend label] {\n}
            }
    ;
    \end{scope}
}

\begin{document}

\begin{figure}[!htbp]
\centering
% \footnotesize
\sffamily
\noindent\begin{tikzpicture}
[
    pie chart,
    slice type={comet}{blu},
    slice type={legno}{rosso},
    slice type={coltello}{giallo},
    slice type={sedia}{viola},
    slice type={caffe}{verde},
    pie values/.style={font={\small}},
    scale=2
]

    \pie{2008}{73/comet,13/legno,7/sedia,7/coltello}
    \pie[xshift=2.2cm,values of coltello/.style={pos=1.1}]%
        {2009}{52/comet,23/legno,17/sedia,3/coltello,5/caffe}
    \pie[xshift=4.4cm,values of caffe/.style={pos=1.1}]%
        {2010}{56/comet,26/legno,9/sedia,7/coltello,2/caffe}

    \legend[shift={(0cm,-1cm)}]{{Comet (Pordenone)}/comet, {Wood and furniture (Livenza)}/legno, {Knife (Maniago)}/coltello}
    \legend[shift={(3cm,-1cm)}]{{Chair (Manzano)}/sedia, {Coffee (Trieste)}/caffe}

\end{tikzpicture}
\caption{This is a caption}
\label{fig:this-is-a-label}
\end{figure}

\end{document}
7

Are you sure you want to do this? The use of patterns produces a result which might seem to be "too crowded", in my opinion.

The new style slice type pattern allows you to specify patterns, in a similar fashion in which you specify filling colors with slice type.

\documentclass{article}
\usepackage{tikz,pgf} 

\definecolor{rosso}{RGB}{220,57,18}
\definecolor{giallo}{RGB}{255,153,0}
\definecolor{blu}{RGB}{102,140,217}
\definecolor{verde}{RGB}{16,150,24}
\definecolor{viola}{RGB}{153,0,153}

\makeatletter

\tikzstyle{chart}=[
    legend label/.style={font={\scriptsize},anchor=west,align=left},
    legend box/.style={rectangle, draw, minimum size=5pt},
    axis/.style={black,semithick,->},
    axis label/.style={anchor=east,font={\tiny}},
]

\tikzstyle{bar chart}=[
    chart,
    bar width/.code={
        \pgfmathparse{##1/2}
        \global\let\bar@w\pgfmathresult
    },
    bar/.style={very thick, draw=white},
    bar label/.style={font={\bf\small},anchor=north},
    bar value/.style={font={\footnotesize}},
    bar width=.75,
]

\tikzstyle{pie chart}=[
    chart,
    slice/.style={line cap=round, line join=round, very thick,draw=white},
    pie title/.style={font={\bf}},
    slice type/.style 2 args={
        ##1/.style={fill=##2},
        values of ##1/.style={}
    },
    slice type pattern/.style 2 args={
        ##1/.style={pattern=##2},
        values of ##1/.style={}
    }
]

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\usetikzlibrary{patterns}

\newcommand{\pie}[3][]{
    \begin{scope}[#1]
    \pgfmathsetmacro{\curA}{90}
    \pgfmathsetmacro{\r}{1}
    \def\c{(0,0)}
    \node[pie title] at (90:1.3) {#2};
    \foreach \v/\s in{#3}{
        \pgfmathsetmacro{\deltaA}{\v/100*360}
        \pgfmathsetmacro{\nextA}{\curA + \deltaA}
        \pgfmathsetmacro{\midA}{(\curA+\nextA)/2}

        \path[slice,\s] \c
            -- +(\curA:\r)
            arc (\curA:\nextA:\r)
            -- cycle;
        \pgfmathsetmacro{\d}{max((\deltaA * -(.5/50) + 1) , .5)}

        \begin{pgfonlayer}{foreground}
        \path \c -- node[pos=\d,pie values,values of \s]{$\v\%$} +(\midA:\r);
        \end{pgfonlayer}

        \global\let\curA\nextA
    }
    \end{scope}
}

\newcommand{\legend}[2][]{
    \begin{scope}[#1]
    \path
        \foreach \n/\s in {#2}
            {
                  ++(0,-10pt) node[\s,legend box] {} +(5pt,0) node[legend label] {\n}
            }
    ;
    \end{scope}
}

\begin{document}

\begin{figure}%[!htbp]
\centering
% \footnotesize
\sffamily
\begin{tikzpicture}
[
    pie chart,
    slice type pattern={comet}{bricks},
    slice type pattern={legno}{crosshatch dots},
    slice type pattern={coltello}{north east lines},
    slice type pattern={sedia}{checkerboard},
    slice type pattern={caffe}{horizontal lines},
    pie values/.style={font={\small}},
    scale=2
]

    \pie{2008}{73/comet,13/legno,7/sedia,7/coltello}
    \pie[xshift=2.2cm,values of coltello/.style={pos=1.1}]%
        {2009}{52/comet,23/legno,17/sedia,3/coltello,5/caffe}
    \pie[xshift=4.4cm,values of caffe/.style={pos=1.1}]%
        {2010}{56/comet,26/legno,9/sedia,7/coltello,2/caffe}

    \legend[shift={(0cm,-1cm)}]{{Comet (Pordenone)}/comet, {Wood and furniture (Livenza)}/legno, {Knife (Maniago)}/coltello}
    \legend[shift={(3cm,-1cm)}]{{Chair (Manzano)}/sedia, {Coffee (Trieste)}/caffe}


\end{tikzpicture}
\caption{Pie charts of the population distribution by survival time of the breast cancer datasets preprocessed from SEER.}
\label{fig:preprocess-seer-pop-pie}
\end{figure}

\end{document}

enter image description here

  • 1
    ooh this is so cool! :) Is there any tomato pattern, by the way? I'd love to have some pizza right now. :) – Paulo Cereda Mar 1 '14 at 12:18
3

The previous reply answers the question, but in order to make the % numbers visible, you can use the fill key for the node command.

   \begin{pgfonlayer}{foreground}
    \path \c -- node[fill=white,pos=\d,pie values,values of \s]{$\v\%$} +(\midA:\r);
    \end{pgfonlayer}
  • Very good addition! My compliments. Welcome to TeX.SE! – Jan Jan 20 '17 at 9:07

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.