# Tikz - Pie chart with many data

I am trying to present data in a pie chart using Tikz. I used the pie chart example from texample.net.

My problem is that I want to present a lot data, therefore many slices and as a result the pie chart looks ugly...

Any idea on how to make it more clean and clear?

A code that reproduces the figure can be seen below

\documentclass{article}

\usepackage{tikz}
\usepackage{calc}
\usepackage{ifthen}

\begin{document}

\newcommand{\slice}[4]{
\pgfmathparse{0.5*#1+0.5*#2}
\let\midangle\pgfmathresult

% slice
\draw[thick,fill=black!10] (0,0) -- (#1:1) arc (#1:#2:1) -- cycle;

% outer label
\node[label=\midangle:#4] at (\midangle:1) {};

% inner label
\pgfmathparse{min((#2-#1-10)/110*(-0.3),0)}
\let\temp\pgfmathresult
\pgfmathparse{max(\temp,-0.5) + 0.8}
\let\innerpos\pgfmathresult
\node at (\midangle:\innerpos) {#3};
}

\begin{tikzpicture}[scale=5]

\newcounter{a}
\newcounter{b}
\foreach \p/\t in {3/Argentina,
1/Armenia,
7/Belgium,
2/Brazil,
2/Bulgaria,
37/China,
6/China-Taiwan,
6/Czech Republic,
4/Finland,
58/France,
8/Germany,
4/Hungary,
22/India,
1/Iran,
42/Japan,
2/Mexico,
1/Netherlands,
4/Pakistan,
25/Republic of Korea,
2/Romania,
35/Russia,
4/Slovakia,
1/Slovenia,
2/South Africa,
7/Spain,
10/Sweeden,
5/Switzerland,
15/Ukraine,
15/United Kingdom,
99/United States of America
}
{
\setcounter{a}{\value{b}}
\slice{\thea/449*360}
{\theb/449*360}
{\p}{\t}
}

\end{tikzpicture}

\end{document}


• Pie charts are for children or people who does not know any better. blog.funnel.io/… Jun 5 '18 at 10:45
• Considering hpekristiansen's comment, would you be interested in a simple bar chart? Jun 5 '18 at 11:00
• @TorbjørnT. Thank you very much for your comment! A bar chart could work indeed. The thing is that it would be nice to have the option to use a pie chart with so many entries. And I think that a bar chart would look busy as well. Jun 5 '18 at 11:58
• If you want to still use pie chart, you could do a first chart with all the mayor field (like the states that have at least 20) and a field that group all the minor field (like the states that have at most 20). In another pie chart you show the field that were grouped. Jun 5 '18 at 13:41
• @gvgramazio : Thank you very much for your suggestion. This could work, but I don't know how to do it efficiently... You think it's impossible in one single pie? Jun 5 '18 at 14:18

A very basic bar chart is quite easy to make, whether it is busy or not I'll leave for you to judge. The obvious benefit is that you have no problems with overlapping labels. The two-column option is in case one wishes to save vertical space, though it does reduce comparability some.

\documentclass{article}
\usepackage{tikz}
\tikzset{
barlabels/.style={font=\footnotesize\sffamily},
declare function={
barheight=5pt;
}
}
\begin{document}
\begin{center}
\begin{tikzpicture}[
y=0.3cm,
x=0.06cm,
]

\foreach [count=\i from 0] \p/\t in
{3/Argentina,
1/Armenia,
7/Belgium,
2/Brazil,
2/Bulgaria,
37/China,
6/China-Taiwan,
6/Czech Republic,
4/Finland,
58/France,
8/Germany,
4/Hungary,
22/India,
1/Iran,
42/Japan,
2/Mexico,
1/Netherlands,
4/Pakistan,
25/Republic of Korea,
2/Romania,
35/Russia,
4/Slovakia,
1/Slovenia,
2/South Africa,
7/Spain,
10/Sweden,
5/Switzerland,
15/Ukraine,
15/United Kingdom,
99/United States of America
}
{
\node [anchor=base east,
barlabels,
name=i-\i] at (0,-\i) {\t};
\fill [blue!40] (i-\i.base east) rectangle ++(\p,barheight)  ++(0,-barheight)
node[barlabels,
black,
anchor=base west] {\p};
}

\end{tikzpicture}

\bigskip

Two columns:

\bigskip

\begin{tikzpicture}[
y=0.3cm,
x=0.04cm,
barlabels/.style={font=\footnotesize\sffamily}
]

\foreach [count=\i from 0] \p/\t in
{3/Argentina,
1/Armenia,
7/Belgium,
2/Brazil,
2/Bulgaria,
37/China,
6/China-Taiwan,
6/Czech Republic,
4/Finland,
58/France,
8/Germany,
4/Hungary,
22/India,
1/Iran,
42/Japan,
2/Mexico,
1/Netherlands,
4/Pakistan,
25/Republic of Korea,
2/Romania,
35/Russia,
4/Slovakia,
1/Slovenia,
2/South Africa,
7/Spain,
10/Sweden,
5/Switzerland,
15/Ukraine,
15/United Kingdom,
99/United States of America
}
{
\node [anchor=base east,
barlabels,
name=i-\i] at ({ifthenelse(\i < 16,0,150)},{-mod(\i,16)}) {\t};
\fill [blue!40] (i-\i.base east) rectangle ++(\p,barheight)  ++(0,-barheight)
node[barlabels,
black,
anchor=base west] {\p};
}

\end{tikzpicture}
\end{center}
\end{document}


I guess if you must have a pie chart with that many small slices, you need some way of avoiding overlap, for example by moving individual labels. This very simple modification to your code adds two arguments to the \slice macro, and two corresponding loop variables. The first one is for shifting the text labels by (x,y), the second for moving the number radially (it is a factor that the radius is multiplied with). I also moved the slices themselves to the background layer, so they don't cover the numbers.

I'm not claiming this is pretty, and there are probably better ways of doing it, but it shows one way of making the diagram readable. Sort of.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{backgrounds}
\begin{document}

\newcommand{\slice}[6]{
\pgfmathparse{0.5*#1+0.5*#2}
\let\midangle\pgfmathresult

% slice
\scoped[on background layer]
\draw[thick,fill=black!10] (0,0) -- (#1:1) arc (#1:#2:1) -- cycle;

% outer label
\node[label={[shift={#5}]\midangle:#4}] at (\midangle:1) {};

% inner label
\pgfmathparse{min((#2-#1-10)/110*(-0.3),0)}
\let\temp\pgfmathresult
\pgfmathparse{max(\temp,-0.5) + 0.8}
\let\innerpos\pgfmathresult
\node [inner sep=1pt,circle,fill=black!10] at (\midangle:\innerpos*#6) {#3};
}

\begin{tikzpicture}[scale=5]

\newcounter{a}
\newcounter{b}
\foreach \p/\t/\nodeshift/\numbershift in
{3/Argentina/{(0,-0.1)}/1.1,
1/Armenia/{(0,0.1)}/1,
7/Belgium/{(0,-0.1)}/0.9,
2/Brazil/{(0,0)}/1.1,
2/Bulgaria/{(0,0.1)}/1,
37/China/{(0,0)}/1,
6/China-Taiwan/{(0,0)}/1,
6/Czech Republic/{(0,0.4)}/1,
4/Finland/{(-0.5,0)}/1,
58/France/{(0,0)}/1,
8/Germany/{(0,0)}/1,
4/Hungary/{(0,0)}/1,
22/India/{(0,0)}/1,
1/Iran/{(0,0)}/1,
42/Japan/{(0,0)}/1,
2/Mexico/{(0,0.2)}/0.9,
1/Netherlands/{(0,0)}/1,
4/Pakistan/{(0,-0.2)}/1.1,
25/Republic of Korea/{(0,0)}/1,
2/Romania/{(0,0)}/1,
35/Russia/{(0,0)}/1,
4/Slovakia/{(0,0.4)}/0.7,
1/Slovenia/{(0,0.2)}/0.8,
2/South Africa/{(0,0)}/0.9,
7/Spain/{(0,-0.1)}/1,
10/Sweden/{(0,-0.15)}/1,
5/Switzerland/{(0,-0.3)}/1,
15/Ukraine/{(0.4,0.2)}/1,
15/United Kingdom/{(0,0)}/1,
99/United States of America/{(0,0)}/1}
{
\setcounter{a}{\value{b}}

• You have an extra e in Sweden by the way. Jun 5 '18 at 13:30