4

I am trying to implement Bordaigorl's answer to create pie charts with patterns. However, with my MWE I get the following errors:

Package pgfkeys Error: I do not know the key '/tikz/slice type/.style 3 args' and I am going to ignore it. Perhaps you misspelled it.

I modified the slice type (in MWE) in pie chart to get a third argument for patterns, which does not work as I expected. How to get patterns in slice types in Tikz pgf?

MWE

\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{patterns}
\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 3 args={
        ##1/.style={fill=##2,pattern=##3},
        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{tikzpicture}
[
    pie chart,
    slice type={comet}{blu,dots},
    slice type={legno}{rosso,grid},
    slice type={coltello}{giallo,north west lines},
    slice type={sedia}{viola,crosshatch},
    slice type={caffe}{verde,vertical 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}
\end{document}
  • 3 args needs 3 args {comet}{blu,dots} is 2 args – percusse Oct 1 '17 at 14:19
  • 1
    @percusse style 3 args doesn't even exist, does it? There's 2 args and n args. – Torbjørn T. Oct 1 '17 at 16:27
  • @TorbjørnT. Ouch. I need coffee :) – percusse Oct 1 '17 at 16:29
4

First of all, there is no such thing as style 3 args. There is style n args, but that is used as

stylename/.style n args={<number of arguments>}{<style definition>}

So you need to change the syntax of your style definition to

slice type/.style n args={3}{ ... }

And having done that, you need to take percusses' comment into account, and use

slice type={comet}{blu}{dots}

not

slice type={comet}{blu,dots}

as the latter has two arguments, not three.

Finally I changed from \tikzstyle to \tikzset, as the former is considered deprecated, and I changed from \bf to \bfseries as \bf has been deprecated for about 25 years.

output of code

\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{patterns}
\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}



\tikzset{
  chart/.style={
    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}},
  },
  bar chart/.style={
    chart,
    bar width/.code={
        \pgfmathparse{##1/2}
        \global\let\bar@w\pgfmathresult
    },
    bar/.style={very thick, draw=white},
    bar label/.style={font={\bfseries\small},anchor=north},
    bar value/.style={font={\footnotesize}},
    bar width=.75,
  },
  pie chart/.style={
    chart,
    slice/.style={line cap=round, line join=round, very thick,draw=white},
    pie title/.style={font={\bfseries}},
    slice type/.style n args={3}{
        ##1/.style={pattern color=##2,pattern=##3},
        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{tikzpicture}
[
    pie chart,
    slice type={comet}{blu}{dots},
    slice type={legno}{rosso}{grid},
    slice type={coltello}{giallo}{north west lines},
    slice type={sedia}{viola}{crosshatch},
    slice type={caffe}{verde}{vertical 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}
\end{document}
  • Why doesn't the pattern have colours? – nxkryptor Oct 2 '17 at 3:48
  • @nxkryptor Oops, sorry, didn't even notice that. You need to set pattern color, not fill. And my comment about moving slice type out of pie chart was wrong, I had at some point changed from ## to #. – Torbjørn T. Oct 2 '17 at 5:52

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.