饼图中的隐藏数字

饼图中的隐藏数字

想要提取饼图中隐藏或不清楚的数字,并将它们显示为附图中的“带线的红色数字”。以下是我的代码

\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}

在此处输入图片描述

答案1

您可能更愿意使用另一种方式来绘制饼图,因为该pgf-pie包在自定义方面不太灵活。话虽如此,我在原始包中添加了一些相关功能,增加了一些选项(目前仅影响样式polar):

  • number as pin if below(默认值0):如果数字的相关值低于给定的阈值,则将数字的样式更改为大头针;
  • shift label if below(默认值0):如果数字的相关值低于给定的阈值,则将标签向外移动;
  • shift label(默认值0pt):按给定值将标签向外移动。

通过这些更改,可以执行以下操作:

\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}

在此处输入图片描述


该文件tikzlibrarypie.code.tex需要修改如下:

  1. 将的定义替换为\pgfpie@slice

    \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}{<}{\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. 添加\newdimen\pgfpie@shiftLabelDist其他尺寸的定义位置。

  3. 添加以下选项到\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. 添加以下选项到\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. 替换定义\pgfpie@@pie(作为包装\scope宏的选项):

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

您可以使用etoolbox修补原始宏:

\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}{<}{\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}

修改后的文件的完整代码tikzlibrarypie.code.tex如下:

% 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}{<}{\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}{>}{\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@sliceLength*0.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
}

答案2

在此处输入图片描述

我尝试从头开始创建图表作为pic元素。pie它的第二个参数是比例;它可能会直接在本地缩放 pic 元素,但在我的测试中这并不令人信服。

代码

\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/\NbS*360;
          \am = (\j +.5)/\NbS*360;
          {%
            \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}

答案3

以下答案使用轮图包,是我写的。

请注意,原始问题中的一些百分比是错误的:2020 年应该是 15% 而不是 16%;2021 年应该是 20% 而不是 21%;2022 年应该是 34% 而不是 35%。

切片通过键进行移动explode

使用键值对来指定颜色列表WClistcolors。这些颜色可以与宏一起使用\WClistcolors

定义一个命令\WCtest,其输出取决于第一个变量是否小于 5。此命令用于键datalineswheel data

在此处输入图片描述

\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}

相关内容