1

I always have trouble getting charts properly centered. They always seem to stagger off to the right hand side of the page. Notice how the example images are perfectly centered as if they're a single figure, but the charts aren't. Their captions' appear to be centered properly, but the charts are off kilter with respect to their captions. I tried to fix it with minipages and makeboxes and so on, but I can't figure it out. What's the solution? Cheers.


enter image description here


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass{article}
\usepackage{xcolor,tikz}
\usetikzlibrary{backgrounds}
\definecolor{NR}{HTML}{D43F3A}
\definecolor{NO}{HTML}{EE9336}
\definecolor{NY}{HTML}{FDC431}
\definecolor{NG}{HTML}{3FAE49}
\definecolor{NB}{HTML}{0071B9}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfkeys{/donut/.cd,
inner radius/.initial=1cm,
inner radius=1cm,
outer radius/.initial=3.14cm,
outer radius=3.14cm,
text color/.initial=white,
text color=white}
\newcommand{\donutchart}[2][]{% Calculate total
   \pgfmathsetmacro{\totalnum}{0}
   \foreach [count=\n] \value/\colour/\name in {#2} {
     \pgfmathparse{\value+\totalnum}
     \global\let\totalnum=\pgfmathresult
     \xdef\numitems{\n}}
  \begin{tikzpicture}
  \pgfmathsetmacro{\wheelwidth}{\pgfkeysvalueof{/donut/outer
  radius}-\pgfkeysvalueof{/donut/inner radius}}
  \pgfmathsetmacro{\midradius}{(\pgfkeysvalueof{/donut/outer radius}
  +\pgfkeysvalueof{/donut/inner radius})/2}
  \begin{scope}[#1]
    \pgfmathsetmacro{\cumnum}{0}
    \foreach \value/\colour/\name in {#2} {
        \pgfmathsetmacro{\newcumnum}{\cumnum + \value/\totalnum*360}
        \pgfmathsetmacro{\midangle}{-(\cumnum+\newcumnum)/2}
        \begin{scope}[on background layer]
          \filldraw[draw=white,fill=\colour]
          (-\cumnum:\pgfkeysvalueof{/donut/outer radius}) 
          arc(-\cumnum:-(\newcumnum):\pgfkeysvalueof{/donut/outer radius}) --
          (-\newcumnum:\pgfkeysvalueof{/donut/inner radius}) 
          arc(-\newcumnum:-(\cumnum):\pgfkeysvalueof{/donut/inner radius}) -- cycle;
        \end{scope}
        \draw node [text=\pgfkeysvalueof{/donut/text color}, 
        font=\bfseries\sffamily] at 
        (\midangle:{\pgfkeysvalueof{/donut/inner radius}+\wheelwidth/2}) {\name};
        \global\let\cumnum=\newcumnum}
  \end{scope}
  \end{tikzpicture}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}
    \centering
    \begin{minipage}{0.45\textwidth}
        \centering
        \donutchart[rotate=45,]{1/NR/, 1/NO/, 20/NY/, 5/NG/, 73/NB/} 
        \caption{Caption 1}
    \end{minipage}\hfill
    \begin{minipage}{0.45\textwidth}
        \centering
        \donutchart[rotate=45]{1/NR/, 1/NO/, 20/NY/, 5/NG/, 73/NB/}
        \caption{Caption 2}
    \end{minipage}\hfill
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}
    \centering
    \begin{minipage}{0.45\textwidth}
        \centering
        \includegraphics[width=1\textwidth]{example-image-a}
        \caption{Caption 3}
    \end{minipage}\hfill
    \begin{minipage}{0.45\textwidth}
        \centering
        \includegraphics[width=1\textwidth]{example-image-b}
        \caption{Caption 4}
    \end{minipage}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}

References:

Drawing a white line/gap after each sector in pie/donut chart
How do I create a donut (or ring) chart in Overleaf?

voices
  • 2,039
  • 3
    Hmmmh, are these donut charts your invention? If not, could you kindly add the link to the source of the code? (The issue seem to be spurious spaces that can be fixed by moving \begin{tikzpicture} before \pgfmathsetmacro{\totalnum}{0}.) –  Oct 29 '19 at 22:47
  • Your "donut" are to wide, so image with them protrude right text border. Make them smaller. – Zarko Oct 29 '19 at 22:55
  • Another issue is that you leave some nodes empty. They are still there and take space, even though they are empty. –  Oct 29 '19 at 22:58
  • @Zarko And if I want them larger? There's plenty of room on the page. – voices Oct 30 '19 at 01:30

1 Answers1

2

There are three comments, and all of them are true:

  1. Spurious spaces;
  2. Empty nodes that contribute to the bounding box;
  3. Your dimensions are too large to fit, as pointed out by Zarko.

However, according to what I find the main effect is that the bounding box computation is wrong for the arcs. The longer they get, the more severe the problem becomes. The long arc is on the left, so this causes a substantial shift to the right. So I solved this problem by clipping by hand the correct bounding box of the circle. Other than that,

  1. I took care of the spaces by moving \begin{tikzpicture} up.
  2. Made sure that the nodes will only be added if they are not empty.
  3. Decreased the dimensions bit.

The result is

\documentclass{article}
\usepackage{xcolor,tikz}
\usetikzlibrary{backgrounds}
\definecolor{NR}{HTML}{D43F3A}
\definecolor{NO}{HTML}{EE9336}
\definecolor{NY}{HTML}{FDC431}
\definecolor{NG}{HTML}{3FAE49}
\definecolor{NB}{HTML}{0071B9}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfkeys{/donut/.cd,
inner radius/.initial=1cm,
inner radius=1cm,
outer radius/.initial=3.14cm,
outer radius=0.5\textwidth-0.5*\pgflinewidth,
text color/.initial=white,
text color=white}
\newcommand{\donutchart}[2][]{% Calculate total
  \begin{tikzpicture}
   \pgfmathsetmacro{\totalnum}{0}
   \foreach [count=\n] \value/\colour/\name in {#2} {
     \pgfmathparse{\value+\totalnum}
     \global\let\totalnum=\pgfmathresult
     \xdef\numitems{\n}}
  \pgfmathsetmacro{\wheelwidth}{\pgfkeysvalueof{/donut/outer
  radius}-\pgfkeysvalueof{/donut/inner radius}}
  \pgfmathsetmacro{\midradius}{(\pgfkeysvalueof{/donut/outer radius}
  +\pgfkeysvalueof{/donut/inner radius})/2}
  \path (-\pgfkeysvalueof{/donut/outer radius}-\pgflinewidth/2,
          -\pgfkeysvalueof{/donut/outer radius}-\pgflinewidth/2) coordinate(bl)
          (\pgfkeysvalueof{/donut/outer radius}+\pgflinewidth/2,
          \pgfkeysvalueof{/donut/outer radius}+\pgflinewidth/2) coordinate (tr);
  \begin{scope}
    \pgfmathsetmacro{\cumnum}{0}
    \foreach \value/\colour/\name in {#2} {
        \pgfmathsetmacro{\newcumnum}{\cumnum + \value/\totalnum*360}
        \pgfmathsetmacro{\midangle}{-(\cumnum+\newcumnum)/2}
        \begin{scope}[on background layer]
          \clip (bl) rectangle (tr);
          \filldraw[draw=white,fill=\colour,#1]
          (-\cumnum:\pgfkeysvalueof{/donut/outer radius}) 
          arc(-\cumnum:-(\newcumnum):\pgfkeysvalueof{/donut/outer radius}) --
          (-\newcumnum:\pgfkeysvalueof{/donut/inner radius}) 
          arc(-\newcumnum:-(\cumnum):\pgfkeysvalueof{/donut/inner radius}) -- cycle;
        \end{scope}
        \ifx\name\empty
        \else
         \draw node [text=\pgfkeysvalueof{/donut/text color}, 
         font=\bfseries\sffamily] at 
         (\midangle:{\pgfkeysvalueof{/donut/inner radius}+\wheelwidth/2}) {\name};
        \fi
        \global\let\cumnum=\newcumnum}
  \end{scope}
  \end{tikzpicture}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}
    \centering
    \begin{minipage}{0.45\textwidth}
        \centering
        \donutchart[rotate=45,]{1/NR/, 1/NO/, 20/NY/, 5/NG/, 73/NB/} 
        \caption{Caption 1}
    \end{minipage}\hfill
    \begin{minipage}{0.45\textwidth}
        \centering
        \donutchart[rotate=45]{1/NR/, 1/NO/, 20/NY/, 5/NG/, 73/NB/}
        \caption{Caption 2}
    \end{minipage}\hfill
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{figure}
    \centering
    \begin{minipage}{0.45\textwidth}
        \centering
        \includegraphics[width=1\textwidth]{example-image-a}
        \caption{Caption 3}
    \end{minipage}\hfill
    \begin{minipage}{0.45\textwidth}
        \centering
        \includegraphics[width=1\textwidth]{example-image-b}
        \caption{Caption 4}
    \end{minipage}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}

enter image description here

  • 1
    P.S. If you consider linking to the source of the code, people like me will happily upvote your question. –  Oct 30 '19 at 00:04
  • I have no idea where the original came from, it's just a thing I salvaged from an old assignment. It's probably from texample.net, or maybe even from here. I'll see if I can find it for ya. – voices Oct 30 '19 at 01:24
  • Here ya go. https://tex.stackexchange.com/q/301199 https://tex.stackexchange.com/q/453507 – voices Oct 30 '19 at 01:37
  • So thanks for the response, but it's important that the charts be allowed to retain their size. Not necessarily for the MWE, but in practice with real documents. – voices Oct 30 '19 at 01:56
  • @voices I believe I have made them as large as consistent with the boundary conditions. If you want them larger, you need to either change the page geometry, or increase the widths of the minipages, or both. BTW, I believe this question came up somewhere in connection with the truly original code, or one of its descendants. So if everyone would link in their post where the code comes from, they would most likely find the solution themselves, or at least spare those who work on an answer from having to reinvent the wheel. Well, attempting to avoid a conflict I give you +1. ;-) –  Oct 30 '19 at 02:29
  • What conflict. You asked for references so I dug em up for ya. That's what you wanted isn't it. Surely there's a way to exceed the margin, if I increase the size they start to hang over the right-hand side. So I assume we can split the difference and hang over both just a little bit. Share the burden as it were. I should be able to make them each as wide as the entire page, with each one half on-half off. If I really wanted to. – voices Oct 30 '19 at 03:49
  • Off-topic. Oh no, the OP quoted an answer provided by the user Schrödinger's cat and he did not know it!! – manooooh Oct 30 '19 at 04:22
  • It was very helpful that the three comments were true. So all the others comments of other users are false. My god what a silly I was. :) – manooooh Oct 30 '19 at 04:24
  • 1
    @manooooh No, full credit should go users like Mark Wibrow, who is one of those who pioneered this. But this is less about the credit than that if there were the links, it would be so much easier for all involved users to gauge which approaches already exist, simply because they are linked. –  Oct 30 '19 at 04:25