3

I am trying to build the following pie chart with latex and the code below, however it seems quite difficult to match the legend, colors palette and external circle grouping colors.

enter image description here

\documentclass[tikz,border=10pt]{standalone}
\begin{document}
\def\angle{0}
\def\radius{3}
\def\cyclelist{{"orange","blue","red","green"}}
\newcount\cyclecount \cyclecount=-1
\newcount\ind \ind=-1
\begin{tikzpicture}[nodes = {font=\sffamily}]
 \foreach \percent/\name in {
  0.01/1\% Cash,
  4.26/ 5\% Miton Multi-Cap Income,
  6.86/6\% Schroder Income Maximiser,
  3.82/6\% Trojan Income,
  3.32/7\% CF Woodford Equity Income,
  2.91/7\% Artemis Global Income,
  2.87/4\% First State Global Listed Infraestructure
  2.63/4\% Lazard Global Listed Infraestructure
  3.50/4\% Legg Mason RARE Global Income
  2.55/6\% Newton Global Income
  4.6/5\% Henderson Strategic Bond
  5.01/4\% Invesco Perpetual Monthly Income Plus
  4.4/5\% Jupiter Strategic Bond
  0/4\% L&G All Stocks Index Linked Gilt Index
  2.3/5\% L&G Short Dated Sterling Corporate Bond Index
  5.95/4\% Royal London Short Duration Global High Yield Bond
  3.55/4\% Twenty Four Corporate Bond
  5.03/4\% Twenty Four Dynamic Bond
  4.8/5\% F&C Property Growth & Income
  4.44/5\% Aviva Multi Strategy Target Income
  3.45/5\% Invesco Perpetual Global Targeted Income
} {
  \ifx\percent\empty\else               % If \percent is empty, do nothing
    \global\advance\cyclecount by 1     % Advance cyclecount
    \global\advance\ind by 1            % Advance list index
    \ifnum3<\cyclecount                 % If cyclecount is larger than list
      \global\cyclecount=0              %   reset cyclecount and
      \global\ind=0                     %   reset list index
    \fi
    \pgfmathparse{\cyclelist[\the\ind]} % Get color from cycle list
    \edef\color{\pgfmathresult}         %   and store as \color
    % Draw angle and set labels
    \draw[fill={\color!50},draw={\color}] (0,0) -- (\angle:\radius)
      arc (\angle:\angle+\percent*3.6:\radius) -- cycle;
    \node at (\angle+0.5*\percent*3.6:0.7*\radius) {\percent\,\%};
    \node[pin=\angle+0.5*\percent*3.6:\name]
      at (\angle+0.5*\percent*3.6:\radius) {};
    \pgfmathparse{\angle+\percent*3.6}  % Advance angle
    \xdef\angle{\pgfmathresult}         %   and store in \angle
  \fi
};
\end{tikzpicture}
\end{document}

I found particularly complex to replicate it with latex, so any help will be welcome. Thanks for your support!

3

It's a start:

enter image description here

I added a few counters to the \foreach to replace your \global\advance.. structure. The legend entries are added on a chain, that places them automatically. The number of entries in one arc and the start and stop angle of the arc can be adjusted with \maxLeg and \legBound respectively.

The placing of the nodes inside the wedges is harder and I haven't found a solution for that. Maybe I will ook into it later. (For other users: feel free to use my code as a starting point for a better answer.)

\documentclass[tikz,border=10pt]{standalone}

\usetikzlibrary{chains}

\begin{document}
\def\cyclelist{{"orange","blue","red","green"}}
\pgfmathsetmacro\startAngle{+90}
\pgfmathsetmacro\radius{+5}
\pgfmathsetmacro\maxLeg{+10}
\pgfmathsetmacro\legBound{60}
\pgfmathsetmacro\legSpacing{2*\legBound/\maxLeg}
\begin{tikzpicture}[
    nodes = {font=\sffamily},
    start chain=legend placed {at={(%
        {1.1*\radius*cos(mod(\tikzchaincount-1,\maxLeg)*\legSpacing-\legBound)+(\tikzchaincount-1 >= \maxLeg)*5*floor((\tikzchaincount-1)/\maxLeg)},%
        {1.1*\radius*sin(mod(\tikzchaincount-1,\maxLeg)*\legSpacing-\legBound)}%
    )}}
]
\foreach \percent/\percenttwo/\name [count=\i from 0, evaluate=\i as \ind using {mod(\i,4)},count=\j] in {
    1/1/Cash,
    5/5/Miton Multi-Cap Income,
    6/6/Schroder Income Maximiser,
    6/6/Trojan Income,
    7/7/CF Woodford Equity Income,
    7/7/Artemis Global Income,
    4/4/First State Global Listed Infraestructure,
    4/4/Lazard Global Listed Infraestructure,
    4/4/Legg Mason RARE Global Income,
    6/6/Newton Global Income,
    5/5/Henderson Strategic Bond,
    4/4/Invesco Perpetual Monthly Income Plus,
    5/5/Jupiter Strategic Bond,
    4/4/L\&G All Stocks Index Linked Gilt Index,
    5/5/L\&G Short Dated Sterling Corporate Bond Index,
    4/4/Royal London Short Duration Global High Yield Bond,
    4/4/Twenty Four Corporate Bond,
    4/4/Twenty Four Dynamic Bond,
    5/5/F\&C Property Growth \& Income,
    5/5/Aviva Multi Strategy Target Income,
    5/5/Invesco Perpetual Global Targeted Income,
} {
    \ifx\percent\empty\else               % If \percent is empty, do nothing
        \pgfmathsetmacro\myColor{\cyclelist[\ind]} % Get color from cycle list
        \pgfmathsetmacro\endAngle{\startAngle + \percent * 3.6}
        \pgfmathsetmacro\midAngle{(\startAngle+\endAngle)/2}
        % Draw angle and set labels
        \draw[fill={\myColor!50},draw={\myColor}] (0,0) -- (\startAngle:\radius)
            arc (\startAngle:\endAngle:\radius) -- cycle;
        \node at (\midAngle:0.7*\radius) {\percent\,\%};
        \node[anchor=west,on chain,fill=\myColor!50,circle,inner sep=2pt] {\percenttwo\,\%};
        \node[at={(legend-\j.east)},anchor=west,text width=4cm,font=\sffamily\footnotesize] {\name};
        \xdef\startAngle{\endAngle}         %   and store in \angle
    \fi
};
\end{tikzpicture}
\end{document}

Edit
A small edit that uses the colors from the source image, but no clever way to determine them, simply using a predefined color-list. I also noticed that the legend was drawn the wrong way around.

enter image description here

\documentclass[tikz,border=10pt]{standalone}

\usetikzlibrary{chains}

\definecolor{wedge1}{RGB}{ 190  30  46}
\definecolor{wedge2}{RGB}{ 240  65  54}
\definecolor{wedge3}{RGB}{ 241  90  43}
\definecolor{wedge4}{RGB}{ 247 148  30}
\definecolor{wedge5}{RGB}{  43  56 144}
\definecolor{wedge6}{RGB}{  28 117 188}
\definecolor{wedge7}{RGB}{  40 170 225}
\definecolor{wedge8}{RGB}{ 119 179 225}
\definecolor{wedge9}{RGB}{ 181 212 239}
\definecolor{wedge10}{RGB}{  0 104  56}
\definecolor{wedge11}{RGB}{  0 148  69}
\definecolor{wedge12}{RGB}{ 57 181  74}
\definecolor{wedge13}{RGB}{141 199  63}
\definecolor{wedge14}{RGB}{215 244  34}
\definecolor{wedge15}{RGB}{249 237  50}
\definecolor{wedge16}{RGB}{248 241 148}
\definecolor{wedge17}{RGB}{242 245 205}
\definecolor{wedge18}{RGB}{123  82  49}
\definecolor{wedge19}{RGB}{104  73 158}
\definecolor{wedge20}{RGB}{102  45 145}
\definecolor{wedge21}{RGB}{148 149 151}

\begin{document}
\def\groupTotals{{1,4,5,8,1,2}}
\pgfmathsetmacro\startAngle{90-3.6/2}
\pgfmathsetmacro\radius{+5}
\pgfmathsetmacro\maxLeg{+12}
\pgfmathsetmacro\legBound{+60}
\pgfmathsetmacro\legSpacing{2*\legBound/(\maxLeg-1)}
\begin{tikzpicture}[
    nodes = {font=\sffamily},
    start chain=legend placed {at={(%
        {1.3*\radius*cos(-mod(\tikzchaincount-1,\maxLeg)*\legSpacing+\legBound)+(\tikzchaincount-1 >= \maxLeg)*5*floor((\tikzchaincount-1)/\maxLeg)},%
        {1.3*\radius*sin(-mod(\tikzchaincount-1,\maxLeg)*\legSpacing+\legBound)}%
    )}}
]
\foreach \yield/\percent/\name [count=\i] in {
    4.26/5/Miton Multi-Cap Income,
    6.86/6/Schroder Income Maximiser,
    3.82/6/Trojan Income,
    3.32/7/CF Woodford Equity Income,
    2.91/7/Artemis Global Income,
    2.87/4/First State Global Listed Infraestructure,
    2.63/4/Lazard Global Listed Infraestructure,
    3.50/4/Legg Mason RARE Global Income,
    2.55/6/Newton Global Income,
    4.6 /5/Henderson Strategic Bond,
    5.01/4/Invesco Perpetual Monthly Income Plus,
    4.4 /5/Jupiter Strategic Bond,
    0   /4/L\&G All Stocks Index Linked Gilt Index,
    2.3 /5/L\&G Short Dated Sterling Corporate Bond Index,
    5.95/4/Royal London Short Duration Global High Yield Bond,
    3.55/4/Twenty Four Corporate Bond,
    5.03/4/Twenty Four Dynamic Bond,
    4.8 /5/F\&C Property Growth \& Income,
    4.44/5/Aviva Multi Strategy Target Income,
    3.45/5/Invesco Perpetual Global Targeted Income,
    0.01/1/Cash,
} {
    \ifx\percent\empty\else               % If \percent is empty, do nothing
        \pgfmathsetmacro\endAngle{\startAngle - \percent * 3.6}
        \pgfmathsetmacro\midAngle{(\startAngle+\endAngle)/2}
        % Draw angle and set labels
        \fill[wedge\i] (0,0) -- (\startAngle:\radius)
            arc (\startAngle:\endAngle:\radius) -- cycle;
        \ifnum\i<21
            \node at (\midAngle:0.7*\radius) {\yield\%};
        \fi
        \node[anchor=west,on chain,fill=wedge\i,circle,inner sep=2pt] {\percent\,\%};
        \node[at={(legend-\i.east)},anchor=west,text width=4cm,font=\sffamily\footnotesize] {\name};
        \xdef\startAngle{\endAngle}         %   and store in \angle
    \fi
};
\end{tikzpicture}
\end{document}
| improve this answer | |
  • Good starting point! Thanks a lot! I have modified the percentages (in your code above) to close the chart as I realized that in order to close it (I mean 100%) the slots are precisely the percentages in the legend. I just to figure out how to assign the color codes to each piece of the chart with the legend and to define the colors. Additionally, would be a victory to replicate the legend inside and the legend outside rounding the chart and summing and naming the colored percentages. But again, thanks for the clue!!! – José Aug 27 '18 at 15:01
  • 1
    @José Ah I hadn't noticed that, I simply assumed that the data was not yet complete. – Max Aug 27 '18 at 16:33

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.