I'm trying to create a macro that will take a list of pairs as an argument in order to draw a pie chart. I'm trying to make it so that portions of the pie are specified as a fraction less than 1. Here's a specific example of what I'm trying to accomplish:

\documentclass{article}
\usepackage{pgf,tikz}
\usepackage{ifthen}
\usetikzlibrary{calc}

\begin{document}

\newcounter{a} \newcounter{b}
\newcommand*{\piechart}[1]{
    \begin{tikzpicture}[scale=\textwidth/2cm]
    \setcounter{a}{0} \setcounter{b}{0}
    \foreach \amt/\lbl in {#1}{
        \setcounter{a}{\value{b}}
        \addtocounter{b}{\amt}
        \pgfmathsetmacro{\angleone}{\value{a}*360}
        \pgfmathsetmacro{\angletwo}{\value{b}*360}
        \pgfmathsetmacro{\midangle}{(\angleone+\angletwo)/2}
        \draw[thick] (0,0) -- (\angleone:1) arc (\angleone:\angletwo:1) -- cycle;
        \node at (\midangle:0.6) {\lbl};
    }
    \end{tikzpicture}
}

\piechart{{1/6}/label1, {1/6}/label2, {1/6}/label3, {1/2}/label4}

\end{document}

However, the output currently looks like the following: enter image description here

I'm thinking that there's a problem either with my use of counters, or with how I specify fractional values surrounded by {} in the argument list.

  • 3
    If you don require the chart to be in the interval 0--1, then take a look here: tex.stackexchange.com/a/411579/134574 – Phelype Oleinik Aug 10 at 18:23
  • 1
    counters do not like fractions. I am also wondering why you need them at all. – marmot Aug 10 at 18:24
  • @PhelypeOleinik Thanks for the link! That post has some nice label formatting that I might have to borrow myself. – Arrow M Aug 10 at 21:40
  • Here is another link ... – marmot Aug 10 at 23:23
up vote 3 down vote accepted

I agree with @Phelype that this site has many examples of very nice pie charts, and it might be advantageous to start from those instead of reinventing the wheel. But as I mentioned in my comment, you cannot use counters for fractions. And you have to remember the previous angle to bake the pie.

\documentclass{article}
\usepackage{tikz}

\begin{document}

\newcommand*{\piechart}[1]{
    \begin{tikzpicture}[scale=\textwidth/2cm]
    %\setcounter{a}{0} \setcounter{b}{0}
    \xdef\PrevFraction{0}
    \foreach \amt/\lbl in {#1}{
        \pgfmathsetmacro{\angleone}{\PrevFraction*360}
        \pgfmathsetmacro{\NewFraction}{\PrevFraction+\amt}
        \pgfmathsetmacro{\angletwo}{\NewFraction*360}
        \pgfmathsetmacro{\midangle}{(\angleone+\angletwo)/2}
        \draw[thick] (0,0) -- (\angleone:1) arc (\angleone:\angletwo:1) -- cycle;
        \node at (\midangle:0.6) {\lbl};
        \xdef\PrevFraction{\NewFraction}
    }
    \end{tikzpicture}
}

\piechart{{1/6}/label1, {1/6}/label2, {1/6}/label3, {1/2}/label4}

\end{document}

enter image description here

Counters are TeX's way of representing integers, so you cannot use fractions. TeX represents real numbers with dimensions. Changing your code a little:

enter image description here

\documentclass{article}
\usepackage{tikz}

\begin{document}

\newdimen\a
\newdimen\b
\newcommand*{\piechart}[1]{
    \begin{tikzpicture}[scale=\textwidth/2cm]
    % \setcounter{a}{0} \setcounter{b}{0}
    \global\a=0pt \global\b=0pt
    \foreach \amt/\lbl in {#1}{
        % \setcounter{a}{\value{b}}
        \global\a=\b
        % \addtocounter{b}{\amt}
        \pgfmathsetmacro{\amt}{\amt}
        \global\advance\b \amt pt
        \pgfmathsetmacro{\angleone}{\a*360}
        \pgfmathsetmacro{\angletwo}{\b*360}
        \pgfmathsetmacro{\midangle}{(\angleone+\angletwo)/2}
        \draw[thick] (0,0) -- (\angleone:1) arc (\angleone:\angletwo:1) -- cycle;
        \node at (\midangle:0.6) {\lbl};
    }
    \end{tikzpicture}
}

\piechart{{1/6}/label1, {1/6}/label2, {1/6}/label3, {1/2}/label4}

\end{document}
  • Nice, +1. But you do not need the \strip@pt, \pgfmathsetmacro takes care of that. That way you could remove \makeatletter and \makeatother. (You are also not using ifthen nor calc.) – marmot Aug 10 at 18:39
  • @marmot Neat, I really underestimate PGF :) – Phelype Oleinik Aug 10 at 18:47

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.