5

Want to extract the hidden or unclear numbers in a pie chart and display them like 'red numbers with a line' in the attached figure. Following is my code

\documentclass[acmsmall]{acmart}
\acmJournal{CSUR}

\usepackage{tikz,pgfplots,pgfplotstable} \usepackage{graphicx} \usepackage{pgf-pie, etoolbox}

\begin{document}

\begin{figure}[h] \centering \captionsetup{justification=centering} \begin{tikzpicture} [ every node/.style={align=center}, pin distance=9mm, font={\scriptsize}, scale=0.6 ] \pie [polar, explode=.1]{ 1/2016, 6/2017, 13/2018, 12/2019, 16/2020, 21/2021, 35/2022 } \node (O) at (2,-3.7){(6.1)}; \end{tikzpicture} \begin{tikzpicture} [ every node/.style={align=center}, pin distance=9mm, font={\scriptsize}, scale=0.55 ] \pie [polar, explode=.1]{ 65/aaaaaaaaaaa, 30/bbbbbbbb, 2/cccccc, 3/Other} \node (O) at (0,-3.7){(6.2)}; \end{tikzpicture} \begin{tikzpicture} [ every node/.style={align=center}, pin distance=9mm, font={\scriptsize}, scale=0.55 ] \pie [polar, explode=.1]{ 54/xxxxxxxx, 18/yyyyyyy, 28/zzzzzzzzzzzz}
\node (O) at (0,-3.7){(6.3)}; \end{tikzpicture}
\end{figure
}

\end{document}

enter image description here

Qrrbrbirlbel
  • 119,821

3 Answers3

5

You should probably rather use another way to draw the pie chart, since the pgf-pie package is not really flexible when it comes to customization. Having said that, I added some relevant functionality to the original package which adds a few options (which currently only affect the polar style):

  • number as pin if below (default value 0): change the style of the number to a pin if the relevant value of the number is below the given threshold;
  • shift label if below (default value 0): shift the label outwards if the relevant value of the number is below the given threshold;
  • shift label (default value 0pt): shift the label outwards by the given.

With these changes, it is possible to do the following:

\documentclass[border=10pt]{standalone}
\usepackage{pgf-pie}

\begin{document} \begin{tikzpicture}[ scale=0.6, font={\scriptsize}, pin distance=2mm, pin edge={red}, every pin/.style={ red, inner sep=2pt } ] \pie[ polar, explode=.1, number as pin if below=5, shift label if below=5, shift label=20pt ]{ 1/2016, 6/2017, 13/2018, 12/2019, 16/2020, 21/2021, 35/2022 } \end{tikzpicture} \end{document}

enter image description here


The file tikzlibrarypie.code.tex needs to be amended as follows:

  1. Replace the definition for \pgfpie@slice by:

    \def\pgfpie@slice#1#2#3#4#5#6#7#8{%
      \pgfmathparse{0.5*(#1)+0.5*(#2)}
      \let\pgfpie@midangle\pgfmathresult
    

    \path (#8) -- ++({\pgfpie@midangle}:{#5}) coordinate (pgfpie@O);

    \pgfmathparse{(#7)+(#5)} \let\pgfpie@radius\pgfmathresult

    % slice \draw[line join=round,fill={#6},\pgfpie@style] (pgfpie@O) -- ++({#1}:{#7}) arc ({#1}:{#2}:{#7}) -- cycle;

    \pgfpie@ifchangedirection{% \pgfmathparse{min(((#1)-(#2)-10)/110(-0.3),0)} }{% \pgfmathparse{min(((#2)-(#1)-10)/110(-0.3),0)} }%

    \pgfmathparse{(max(\pgfmathresult,-0.5) + 0.8)*(#7)} \let\pgfpie@innerpos\pgfmathresult

    \pgfpie@ifx\pgfpie@text\pgfpie@text@inside{% % label and number together \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) node[align=center] {\pgfpie@scalefont{#3}\pgfpie@labeltext{#4}\\pgfpie@numbertext{#3}}; }{% % label \pgfpie@ifhidelabel{}{% \pgfpie@iflegend{}{% \pgfpie@ifnum{#3}{<}{\pgfpie@shiftlabelthreshold}{% \pgfmathsetlength{\pgfpie@shiftLabelDist}{\pgfpie@shiftlabel} }{ \pgfmathsetlength{\pgfpie@shiftLabelDist}{0pt} } \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@radius}) node[inner sep=0, \pgfpie@text={[shift={(\pgfpie@midangle:\pgfpie@shiftLabelDist)}]\pgfpie@midangle:#4}] {}; }% }%

    % number
    \pgfpie@ifnum{#3}{&lt;}{\pgfpie@numberpinthreshold}{%
      \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) 
      node[pin={\pgfpie@midangle:{\pgfpie@scalefont{#3}\pgfpie@numbertext{#3}}}] {};
    }{%
      \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) 
      node {\pgfpie@scalefont{#3}\pgfpie@numbertext{#3}};
    }%
    

    }% }

  2. Add \newdimen\pgfpie@shiftLabelDist where the other dimensions are defined.

  3. Add the following options to \pgfqkeys{/pgfpie}:

    number as pin if below/.store in=\pgfpie@numberpinthreshold,
    shift label if below/.store in=\pgfpie@shiftlabelthreshold,
    shift label/.store in=\pgfpie@shiftlabel,
    
  4. Add the following options to \pgfqkeys{/pgfpie}:

    number as pin if below/.store in=\pgfpie@numberpinthreshold,
    shift label if below/.store in=\pgfpie@shiftlabelthreshold,
    shift label/.store in=\pgfpie@shiftlabel,
    
  5. Replace the definition for \pgfpie@@pie (as options to the wrapping \scope macro):

    number as pin if below=0,
    shift label if below=0,
    shift label=0pt,
    

You could use etoolbox to patch the original macros:

\documentclass[border=10pt]{standalone}
\usepackage{pgf-pie, etoolbox}

\makeatletter \patchcmd{\pgfpie@slice}{ \pgfpie@ifx\pgfpie@text\pgfpie@text@inside{% % label and number together \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) node[align=center] {\pgfpie@scalefont{#3}\pgfpie@labeltext{#4}\\pgfpie@numbertext{#3}}; }{% % label \pgfpie@ifhidelabel{}{% \pgfpie@iflegend{}{% \path (pgfpie@O) -- ++ ({\pgfpie@midangle}:{\pgfpie@radius}) node[inner sep=0, \pgfpie@text={\pgfpie@midangle:#4}]{}; }% }%

% number
\path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) node
{\pgfpie@scalefont{#3}\pgfpie@numbertext{#3}};

}% }{ \pgfpie@ifx\pgfpie@text\pgfpie@text@inside{% % label and number together \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) node[align=center] {\pgfpie@scalefont{#3}\pgfpie@labeltext{#4}\\pgfpie@numbertext{#3}}; }{% % label \pgfpie@ifhidelabel{}{% \pgfpie@iflegend{}{% \pgfpie@ifnum{#3}{<}{\pgfpie@shiftlabelthreshold}{% \pgfmathsetlength{\pgfpie@shiftLabelDist}{\pgfpie@shiftlabel} }{ \pgfmathsetlength{\pgfpie@shiftLabelDist}{0pt} } \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@radius}) node[inner sep=0, \pgfpie@text={[shift={(\pgfpie@midangle:\pgfpie@shiftLabelDist)}]\pgfpie@midangle:#4}] {}; }% }%

% number
\pgfpie@ifnum{#3}{&lt;}{\pgfpie@numberpinthreshold}{%
  \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) 
  node[pin={\pgfpie@midangle:{\pgfpie@scalefont{#3}\pgfpie@numbertext{#3}}}] {};
}{%
  \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) 
  node {\pgfpie@scalefont{#3}\pgfpie@numbertext{#3}};
}%

}% }{}{} \newdimen\pgfpie@shiftLabelDist \pgfqkeys{/pgfpie}{ number as pin if below/.store in=\pgfpie@numberpinthreshold, shift label if below/.store in=\pgfpie@shiftlabelthreshold, shift label/.store in=\pgfpie@shiftlabel, } \patchcmd{\pgfpie@@pie}{ hide label=false,
}{ hide label=false, number as pin if below=0, shift label if below=0, shift label=0pt, }{}{} \makeatother

\begin{document} \begin{tikzpicture}[ scale=0.6, font={\scriptsize}, pin distance=2mm, pin edge={red}, every pin/.style={ red, inner sep=2pt } ] \pie[ polar, explode=.1, number as pin if below=5, shift label if below=5, shift label=20pt ]{ 1/2016, 6/2017, 13/2018, 12/2019, 16/2020, 21/2021, 35/2022 } \end{tikzpicture} \end{document}


The full code for the amended file tikzlibrarypie.code.tex would be:

% SPDX-License-Identifier: GPL-2.0-only OR LPPL-1.3c
\RequirePackage{scalefnt}

% % Utilities %

\def\pgfpie@ifx#1#2{% \ifx#1#2% \expandafter\pgfutil@firstoftwo \else \expandafter\pgfutil@secondoftwo \fi}

\def\pgfpie@ifdim#1#2#3{% \ifdim\dimexpr#1\relax#2\dimexpr#3\relax \expandafter\pgfutil@firstoftwo \else \expandafter\pgfutil@secondoftwo \fi}

\def\pgfpie@ifnum#1#2#3{% \ifnum\numexpr#1\relax#2\numexpr#3\relax \expandafter\pgfutil@firstoftwo \else \expandafter\pgfutil@secondoftwo \fi}

\def\pgfpie@ifodd#1{% \ifodd\numexpr#1\relax \expandafter\pgfutil@firstoftwo \else \expandafter\pgfutil@secondoftwo \fi}

\def\pgfpie@newif#1{% \csname newif\expandafter\endcsname\csname ifpgfpie@#1\endcsname \expandafter\def\csname pgfpie@if#1\expandafter\endcsname\expandafter{% \csname ifpgfpie@#1\endcsname \expandafter\pgfutil@firstoftwo \else \expandafter\pgfutil@secondoftwo \fi}% }

% % Constants for text comparison %

\def\pgfpie@text@inside{inside} \def\pgfpie@text@legend{legend} \def\pgfpie@sum@c{100} \def\pgfpie@sum@auto{auto}

% args: % #1: begin angle % #2: end angle % #3: number % #4: label % #5: explode % #6: fill color % #7: radius % #8: center \def\pgfpie@slice#1#2#3#4#5#6#7#8{% \pgfmathparse{0.5(#1)+0.5(#2)} \let\pgfpie@midangle\pgfmathresult

\path (#8) -- ++({\pgfpie@midangle}:{#5}) coordinate (pgfpie@O);

\pgfmathparse{(#7)+(#5)} \let\pgfpie@radius\pgfmathresult

% slice \draw[line join=round,fill={#6},\pgfpie@style] (pgfpie@O) -- ++({#1}:{#7}) arc ({#1}:{#2}:{#7}) -- cycle;

\pgfpie@ifchangedirection{% \pgfmathparse{min(((#1)-(#2)-10)/110(-0.3),0)} }{% \pgfmathparse{min(((#2)-(#1)-10)/110(-0.3),0)} }%

\pgfmathparse{(max(\pgfmathresult,-0.5) + 0.8)*(#7)} \let\pgfpie@innerpos\pgfmathresult

\pgfpie@ifx\pgfpie@text\pgfpie@text@inside{% % label and number together \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) node[align=center] {\pgfpie@scalefont{#3}\pgfpie@labeltext{#4}\\pgfpie@numbertext{#3}}; }{% % label \pgfpie@ifhidelabel{}{% \pgfpie@iflegend{}{% \pgfpie@ifnum{#3}{<}{\pgfpie@shiftlabelthreshold}{% \pgfmathsetlength{\pgfpie@shiftLabelDist}{\pgfpie@shiftlabel} }{ \pgfmathsetlength{\pgfpie@shiftLabelDist}{0pt} } \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@radius}) node[inner sep=0, \pgfpie@text={[shift={(\pgfpie@midangle:\pgfpie@shiftLabelDist)}]\pgfpie@midangle:#4}] {}; }% }%

% number
\pgfpie@ifnum{#3}{&lt;}{\pgfpie@numberpinthreshold}{%
  \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) 
  node[pin={\pgfpie@midangle:{\pgfpie@scalefont{#3}\pgfpie@numbertext{#3}}}] {};
}{%
  \path (pgfpie@O) -- ++({\pgfpie@midangle}:{\pgfpie@innerpos}) 
  node {\pgfpie@scalefont{#3}\pgfpie@numbertext{#3}};
}%

}% }

\def\pgfpie@findColor#1{% \pgfmathparse{int(mod(#1,\the\pgfpie@colorLength))}% \let\pgfpie@ci\pgfmathresult \foreach \pgfpie@c [count=\pgfpie@j from 0] in \pgfpie@color {% \pgfpie@ifnum{\pgfpie@j}{=}{\pgfpie@ci}{% \xdef\pgfpie@thecolor{\pgfpie@c}% \breakforeach }{}% } }

\def\pgfpie@findExplode#1{% \pgfmathparse{int(mod(#1,\the\pgfpie@explodeLength))}% \let\pgfpie@ei\pgfmathresult \foreach \pgfpie@e [count=\pgfpie@j from 0] in \pgfpie@explode {% \pgfpie@ifnum{\pgfpie@j}{=}{\pgfpie@ei}{% \xdef\pgfpie@theexplode{\pgfpie@e}% \breakforeach }{}% }% }

% #1: bottom left point % #2: size % #3: number % #4: color % #5: text \def\pgfpie@square#1#2#3#4#5{% \pgfpie@ifx\pgfpie@text\pgfpie@text@inside{% \draw[fill={#4},\pgfpie@style] (#1) rectangle node[align=center] {\pgfpie@scalefont{#3}\pgfpie@labeltext{#5}\\pgfpie@numbertext{#3}} ++(#2); }{% \draw[fill={#4},\pgfpie@style] (#1) rectangle node {\pgfpie@scalefont{#3}\pgfpie@numbertext{#3}} ++(#2); }% }

% #1: pos % #2: radius % #3: number % #4: color % $5: style % $6: label \def\pgfpie@cloud#1#2#3#4#5#6{% \draw[fill=#4, #5] (#1) circle[radius=#2]; \pgfpie@ifx\pgfpie@text\pgfpie@text@inside{% \node[align=center] at (#1) {\pgfpie@scalefont{#3}\pgfpie@labeltext{#6}\\pgfpie@numbertext{#3}}; }{% \node at (#1) {\pgfpie@scalefont{#3}\pgfpie@numbertext{#3}}; }% }

\newdimen\pgfpie@angleEnd \newdimen\pgfpie@shiftLabelDist \newcount\pgfpie@explodeLength \newcount\pgfpie@colorLength \newcount\pgfpie@sliceLength

\pgfqkeys{/pgfpie}{% .search also={/tikz,/pgf}, explode/.store in=\pgfpie@explode, color/.store in=\pgfpie@color, radius/.store in=\pgfpie@radius, pos/.store in=\pgfpie@pos, style/.store in=\pgfpie@style, before number/.store in=\pgfpie@beforenumber, after number/.code={% \def\pgfpie@afternumber{#1}% \def\pgfpie@late@afternumber{}% }, number as pin if below/.store in=\pgfpie@numberpinthreshold, shift label if below/.store in=\pgfpie@shiftlabelthreshold, shift label/.store in=\pgfpie@shiftlabel, text/.store in=\pgfpie@text, sum/.code={% \def\pgfpie@sum{#1}% \pgfpie@ifx\pgfpie@sum\pgfpie@sum@c{% \def\pgfpie@late@afternumber{\def\pgfpie@afternumber{%}}% }{% \def\pgfpie@late@afternumber{}% }% }, rotate/.store in=\pgfpie@rotate, }

\pgfpie@newif{polar} \pgfqkeys{/pgfpie}{polar/.is if=pgfpie@polar}

\pgfpie@newif{legend}

\pgfpie@newif{changedirection} \pgfqkeys{/pgfpie}{change direction/.is if=pgfpie@changedirection}

\pgfpie@newif{square} \pgfqkeys{/pgfpie}{square/.is if=pgfpie@square}

\pgfpie@newif{cloud} \pgfqkeys{/pgfpie}{cloud/.is if=pgfpie@cloud}

\pgfpie@newif{scalefont} \pgfqkeys{/pgfpie}{scale font/.is if=pgfpie@scalefont} \def\pgfpie@scalefont#1{% \pgfpie@ifscalefont{% \pgfmathparse{(#1) / (\pgfpie@sum) * 3 + 0.9}% \scalefont{\pgfmathresult}% }{}% }

\pgfpie@newif{hidenumber} \pgfqkeys{/pgfpie}{hide number/.is if=pgfpie@hidenumber} \def\pgfpie@numbertext#1{% \pgfpie@ifhidenumber{}{% \pgfpie@beforenumber#1\pgfpie@afternumber }% }

\pgfpie@newif{hidelabel} \pgfqkeys{/pgfpie}{hide label/.is if=pgfpie@hidelabel} \def\pgfpie@labeltext#1{\pgfpie@ifhidelabel{}{#1}}

\pgfpie@newif{numberinlegend} \pgfqkeys{/pgfpie}{number in legend/.is if=pgfpie@numberinlegend} \def\pgfpie@legendnumbertext#1{% \pgfpie@beforenumber#1\pgfpie@afternumber }

\tikzaddtikzonlycommandshortcutlet{\pie}{\pgfpie@pie}%

\def\pgfpie@pie{% \pgfutil@ifnextchar[{\pgfpie@@pie}{\pgfpie@@pie[]}% }

\def\pgfpie@@pie[#1]#2{% \scope[% % to be compatible with "babel" lib handle active characters in nodes=false, % load default parameters /pgfpie/.cd, explode=0, color={blue!60, cyan!60, yellow!60, orange!60, red!60, blue!60!cyan!60, cyan!60!yellow!60, red!60!cyan!60, red!60!blue!60, orange!60!cyan!60}, radius=3, pos={0,0}, style={thick}, before number=, after number=, text=label, sum=100, rotate=0, change direction=false, polar=false, square=false, cloud=false, scale font=false, hide number=false, hide label=false, number as pin if below=0, shift label if below=0, shift label=0pt, every pie/.try,% % load user's parameters #1]

% add percentage automatically \pgfpie@late@afternumber

% legend or not \pgfpie@ifx\pgfpie@text\pgfpie@text@legend{% \pgfpie@legendtrue }{% \pgfpie@legendfalse }%

% handle sum \pgfpie@ifx\pgfpie@sum\pgfpie@sum@auto{% % sum all input \xdef\pgfpie@sum{0}% \foreach \pgfpie@p/\pgfpie@t in {#2} {% \pgfmathparse{(\pgfpie@sum) + (\pgfpie@p)}% \xdef\pgfpie@sum{\pgfmathresult}% }% }{}%

% init counters \global\pgfpie@explodeLength=0 \foreach \pgfpie@e in \pgfpie@explode {% \global\advance\pgfpie@explodeLength by 1 }%

\global\pgfpie@colorLength=0 \foreach \pgfpie@c in \pgfpie@color {% \global\advance\pgfpie@colorLength by 1 }%

\pgfmathsetlength{\pgfpie@angleEnd}{0}%

\global\pgfpie@sliceLength=0 \foreach \pgfpie@p/\pgfpie@e in {#2} {% \global\advance\pgfpie@sliceLength by 1 }%

\pgfpie@ifsquare{% \pgfpie@pie@square{#2}% }{\pgfpie@ifcloud{\pgfpie@pie@cloud{#2}% }{\pgfpie@pie@circle{#2}}}

% legend \pgfpie@ifhidelabel{}{% \pgfpie@iflegend{% \pgfpie@legend{#2}% }{}}% \endscope }

\def\pgfpie@pie@square#1{% \pgfmathparse{(\pgfpie@radius)2} \xdef\pgfpie@verticalLength{\pgfmathresult} \xdef\pgfpie@horizontalLength{\pgfmathresult} \path (\pgfpie@pos) -- ++({-\pgfpie@radius},{-\pgfpie@radius}) coordinate (pgfpie@start); \pgfmathparse{(\pgfpie@verticalLength) (\pgfpie@horizontalLength) / (\pgfpie@sum)} \let\pgfpie@squareUnit\pgfmathresult

% drawing loop \foreach \pgfpie@p/\pgfpie@t [count=\pgfpie@i from 0] in {#1} { \pgfpie@findColor{\pgfpie@i}

\pgfpie@ifdim{\pgfpie@verticalLength cm}{&gt;}{\pgfpie@horizontalLength cm}{%
  \pgfmathparse{(\pgfpie@p) * (\pgfpie@squareUnit) / (\pgfpie@horizontalLength)}
  \let\pgfpie@height\pgfmathresult

  \pgfpie@square{pgfpie@start}{\pgfpie@horizontalLength,\pgfpie@height}
  {\pgfpie@p}
  {\pgfpie@thecolor}
  {\pgfpie@t}
  %label
  \pgfpie@iflegend{}{%
    \pgfpie@ifx\pgfpie@text\pgfpie@text@inside{}{%
      \pgfpie@ifhidelabel{}{%
        \path (pgfpie@start) -- ++({\pgfpie@horizontalLength},{\pgfpie@height*0.5})
        node[inner sep=0, \pgfpie@text={0:{\pgfpie@t}}]{};
      }%
    }%
  }%

  \pgfmathparse{\pgfpie@verticalLength - \pgfpie@height}
  \xdef\pgfpie@verticalLength{\pgfmathresult}
  \path (pgfpie@start) -- ++(0, \pgfpie@height) coordinate (pgfpie@start);
}{%
  \pgfmathparse{(\pgfpie@p) * (\pgfpie@squareUnit) / (\pgfpie@verticalLength)}%
  \let\pgfpie@width\pgfmathresult

  \pgfpie@square{pgfpie@start}{\pgfpie@width,\pgfpie@verticalLength}
  {\pgfpie@p}
  {\pgfpie@thecolor}
  {\pgfpie@t}
  %label
  \pgfpie@iflegend{}{%
    \pgfpie@ifx\pgfpie@text\pgfpie@text@inside{}{%
      \pgfpie@ifhidelabel{}{%
        \path (pgfpie@start) -- ++({\pgfpie@width*0.5},{\pgfpie@verticalLength})
        node[inner sep=0, \pgfpie@text={90:{\pgfpie@t}}]{};
      }%
    }%
  }%

  \pgfmathparse{(\pgfpie@horizontalLength) - (\pgfpie@width)}%
  \xdef\pgfpie@horizontalLength{\pgfmathresult}%
  \path (pgfpie@start) -- ++({\pgfpie@width},0) coordinate (pgfpie@start);
}%

}% }

\def\pgfpie@pie@cloud#1{% % drawing loop \foreach \pgfpie@p/\pgfpie@t [count=\pgfpie@i from 0] in {#1} { % find explode \pgfpie@findExplode{\pgfpie@i} \def\pgfpie@cloudGap{(\pgfpie@theexplode) + 0.1} \pgfmathparse{sqrt((\pgfpie@p) / (\pgfpie@sum)) * (\pgfpie@radius)} \let\pgfpie@cloudR\pgfmathresult \pgfpie@ifnum{\pgfpie@i}{=}{0}{% % first cloud \coordinate (pgfpie@O) at (\pgfpie@pos); \xdef\pgfpie@cloudRone{\pgfpie@cloudR} \xdef\pgfpie@cloudExtendDir{180+(\pgfpie@rotate)} }{\pgfpie@ifnum{\pgfpie@i}{=}{1}{% % second cloud \xdef\pgfpie@cloudRtwo{\pgfpie@cloudR} \xdef\pgfpie@cloudExtendDir{45+(\pgfpie@rotate)} \path (pgfpie@O) -- ++({\pgfpie@cloudExtendDir}:{(\pgfpie@cloudRone)+(\pgfpie@cloudGap)+(\pgfpie@cloudRtwo)}) coordinate (pgfpie@O); }{% % next cloud \pgfmathparse{(\pgfpie@cloudRone)+(\pgfpie@cloudGap)+(\pgfpie@cloudRtwo)} \let\pgfpie@la\pgfmathresult \pgfmathparse{(\pgfpie@cloudRone)+(\pgfpie@cloudGap)+(\pgfpie@cloudR)} \let\pgfpie@lb\pgfmathresult \pgfmathparse{(\pgfpie@cloudRtwo)+(\pgfpie@cloudGap)+(\pgfpie@cloudR)} \let\pgfpie@lc\pgfmathresult \pgfmathparse{(\pgfpie@la)^2+(\pgfpie@lc)^2-(\pgfpie@lb)^2} \let\pgfpie@tmp\pgfmathresult \pgfmathparse{180 - acos((\pgfpie@tmp) / 2 / (\pgfpie@la) / (\pgfpie@lc))} \let\pgfpie@cloudRot\pgfmathresult \pgfpie@ifodd{\pgfpie@i}{% \pgfmathparse{-(\pgfpie@cloudRot)} \let\pgfpie@cloudRot\pgfmathresult }{}% \pgfmathparse{(\pgfpie@cloudExtendDir) - (\pgfpie@cloudRot)} \xdef\pgfpie@cloudExtendDir{\pgfmathresult} \path (pgfpie@O) -- ++({\pgfpie@cloudExtendDir}:{\pgfpie@lc}) coordinate (pgfpie@O); \xdef\pgfpie@cloudRone{\pgfpie@cloudRtwo} \xdef\pgfpie@cloudRtwo{\pgfpie@cloudR} }}%

% find color
\pgfpie@findColor{\pgfpie@i}

\pgfpie@cloud{pgfpie@O}{\pgfpie@cloudR}{\pgfpie@p}
{\pgfpie@thecolor}{\pgfpie@style}{\pgfpie@t}

% label
\pgfpie@iflegend{}{%
  \pgfpie@ifx\pgfpie@text\pgfpie@text@inside{}{%
    \pgfpie@ifhidelabel{}{%
      \path (pgfpie@O) -- ++({\pgfpie@cloudExtendDir}:{\pgfpie@cloudR})
      node[inner sep=0, \pgfpie@text={\pgfpie@cloudExtendDir:{\pgfpie@t}}] {};
    }%
  }%
}%

}% }

\def\pgfpie@pie@circle#1{% \pgfpie@ifpolar{% \xdef\pgfpie@maxValue{0} \foreach \pgfpie@p/\pgfpie@e in {#1} { \pgfmathparse{\pgfpie@p}% \pgfpie@ifdim{\pgfpie@maxValue pt}{<}{\pgfmathresult pt}{% \xdef\pgfpie@maxValue{\pgfpie@p} }{}% } \pgfmathparse{(\pgfpie@sum) / \the\pgfpie@sliceLength} \xdef\pgfpie@polarangle{\pgfmathresult} \pgfmathparse{(\pgfpie@radius) / sqrt(\pgfpie@maxValue)} \xdef\pgfpie@polarRadiusUnit{\pgfmathresult} }{% \xdef\pgfpie@theradius{\pgfpie@radius}% }

\pgfpie@ifchangedirection{% \pgfmathsetlength{\pgfpie@angleEnd}{\pgfpie@sum} }{}% \xdef\pgfpie@angleBegin{\the\pgfpie@angleEnd} % drawing loop \foreach \pgfpie@p/\pgfpie@t [count=\pgfpie@i from 0] in {#1} { \pgfmathsetlength{\pgfpie@angleEnd}{\pgfpie@angleBegin} \pgfpie@ifpolar{% % Polar area diagram \pgfmathaddtolength{\pgfpie@angleEnd}{\pgfpie@polarangle} \pgfmathparse{sqrt(\pgfpie@p) * (\pgfpie@polarRadiusUnit)} \xdef\pgfpie@theradius{\pgfmathresult} }{% % normal pie \pgfpie@ifchangedirection{% \pgfmathaddtolength{\pgfpie@angleEnd}{-(\pgfpie@p)} }{% \pgfmathaddtolength{\pgfpie@angleEnd}{\pgfpie@p} }% }%

% find explode
\pgfpie@findExplode{\pgfpie@i}

% find color
\pgfpie@findColor{\pgfpie@i}
\pgfpie@slice{(\pgfpie@angleBegin)/(\pgfpie@sum)*360+(\pgfpie@rotate)}
{\the\pgfpie@angleEnd/(\pgfpie@sum)*360+(\pgfpie@rotate)}
{\pgfpie@p}
{\pgfpie@t}
{\pgfpie@theexplode}
{\pgfpie@thecolor}
{\pgfpie@theradius}
{\pgfpie@pos}
\xdef\pgfpie@angleBegin{\the\pgfpie@angleEnd}

} }

\def\pgfpie@legend#1{% \coordinate[xshift=0.8cm, yshift={(\the\pgfpie@sliceLength0.5+1)0.5cm}] (pgfpie@legendpos) at (current bounding box.east);

\scope[node distance=0.5cm] \foreach \pgfpie@p/\pgfpie@t [count=\pgfpie@i from 0] in {#1} { \pgfpie@findColor{\pgfpie@i} \node[draw, fill={\pgfpie@thecolor}, \pgfpie@style, below of={pgfpie@legendpos}, label={0:{\pgfpie@t\pgfpie@ifnumberinlegend{~\pgfpie@legendnumbertext{\pgfpie@p}}{}}}] (pgfpie@legendpos) {}; } \endscope }

4

enter image description here

I tried to create the chart from scratch as a pic element, pie. Its second argument is the scale; it might work directly scaling the pic element locally, by it wasn't convincing in my tests.

The code

\documentclass[11pt, margin=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}

\xdefinecolor{rgb0}{RGB}{238, 34, 34} \xdefinecolor{rgb1}{RGB}{255, 102, 17} \xdefinecolor{rgb2}{RGB}{238, 204, 17} \xdefinecolor{rgb3}{RGB}{17, 160, 51} \xdefinecolor{rgb4}{RGB}{17, 170, 187} \xdefinecolor{rgb5}{RGB}{17, 87, 221} \xdefinecolor{rgb7}{RGB}{102, 25, 240} \xdefinecolor{rgb8}{RGB}{153, 0, 238} \xdefinecolor{rgb9}{RGB}{221, 0, 221} \xdefinecolor{rgb6}{RGB}{238, 21, 147} \tikzset{% pics/pie/.style 2 args={% data / scale code={% \foreach \i/\txt [count=\j from 0] in {#1}{% \pgfextra{\xdef\NbS{\j}} } \tikzmath{% integer \NbS, \i, \j; \NbS = int(\NbS +1); real \r, \a, \am; }; \foreach \i/\txt [count=\j from 0] in {#1}{% \tikzmath{% \r = pow(\i/100, .5)#2; \a = \j/\NbS360; \am = (\j +.5)/\NbS360; {% \draw[fill=rgb\j] (\am: #2/75) -- ++(\a: \r) arc (\a: \a +360/\NbS: \r) -- cycle; }; if \i>3 then {% {% \path (\am: .6\r) node[scale=.8] {$\i%$} (\am: {\r +.7}) node[scale=.8] {$\txt$}; }; } else {% {% \path (\am: 2\r) node[scale=.8] {$\txt$}; \draw[red] ({\a +360/(4\NbS)}: \r +.2) -- ([turn]0 :2*\r) ([turn]0 :2ex) node[scale=.8] {$\i%$}; };
}; } } } } }

\begin{tikzpicture} \path (0, 0) pic {pie={1/2016, 6/2017, 23/2018, 2/2019, 16/2020, 21/2021, 35/2022}{7}}; \end{tikzpicture} \end{document}

Daniel N
  • 5,687
3

The answer below uses the wheelchart package, which I wrote.

Note that in the original question, some percentages are wrong: for 2020 it should be 15% instead of 16%, for 2021 20% instead of 21% and for 2022 34% instead of 35%.

The slices are shifted with the key explode.

The colors are specified with a list using the key WClistcolors. These colors can be used with the macro \WClistcolors.

A command \WCtest is defined of which the output depends on whether the first variable is smaller than 5. This command is used in the keys data, lines and wheel data.

enter image description here

\documentclass[border=6pt]{standalone}
\usepackage{wheelchart}
\usepackage{siunitx}
\begin{document}
\pgfkeys{
  /wheelchart,
  counterclockwise,
  explode=0.1,
  radius={0}{0.7*sqrt(\WCvarA)},
  start angle=0,
  value=1,
  WClistcolors={blue!60,cyan!60,yellow!60,orange!60,red!60,blue!60!cyan!60,cyan!60!yellow!60,red!60!cyan!60,red!60!blue!60,orange!60!cyan!60}
}
\def\WCtest#1#2{\ifdim \WCvarA pt<5 pt #1\else #2\fi}
\foreach\WClist [count=\n] in {{1/2016,6/2017,13/2018,12/2019,16/2020,21/2021,35/2022},{65/aaaaaaaaaaa,30/bbbbbbbb,2/cccccc,3/Other},{54/xxxxxxxx,18/yyyyyyy,28/zzzzzzzzzzzz}}{\begin{tikzpicture}
\def\WCsum{0}
\foreach\a/\b in \WClist{\xdef\WCsum{\fpeval{\WCsum+\a}}}
\wheelchart[
  data=\WCtest{\qty{\fpeval{round(100*(\WCvarA/\WCsum),0,1)}}{\percent}}{},
  data angle shift={Mod(\WCmidangle,180)<90?-120/\WCtotalcount:120/\WCtotalcount},
  data sep=0,
  data style=red,
  lines=\WCtest{1.5}{0},
  lines angle shift={Mod(\WCmidangle,180)<90?-120/\WCtotalcount:120/\WCtotalcount},
  lines style=red,
  slices style={fill=none}
]{\WClist}
\wheelchart[
  caption=(6.\n),
  data=\WCvarB,
  slices style={\WClistcolors,draw=black},
  wheel data=\WCtest{}{\qty{\fpeval{round(100*(\WCvarA/\WCsum),0,1)}}{\percent}},
]{\WClist}
\end{tikzpicture}}
\end{document}
matexmatics
  • 4,819