1

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.

Arrow M
  • 45

2 Answers2

3

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.) –  Aug 10 '18 at 18:39
  • @marmot Neat, I really underestimate PGF :) – Phelype Oleinik Aug 10 '18 at 18:47
3

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