如何使用 pgf-pie 创建具有不同文本标签样式的饼图?

如何使用 pgf-pie 创建具有不同文本标签样式的饼图?

我正在尝试创建类似以下的饼图这个。阅读文档后pgf-pie,似乎没有为同一图表中的不同文本提供多种文本样式(等)的选项text=pintext=inside目前,我只能创建这张图表。我理想情况下希望text=inside将其应用于较大的类别,并将text=pin较小的类别的百分比从图表本身中删除,因为它们现在无法读取。

当前代码:

\documentclass[border=5mm]{standalone}
\usepackage{pgf-pie}
\usepackage{etoolbox}
\makeatletter
\patchcmd{\pgfpie@slice}% this is the macro we're patching
{\scalefont{#3}\shortstack{#4\\\beforenumber#3\afternumber}}% find this
{\scalefont{#3}#4}% and replace with this
{}{}
\makeatother
\begin{document}

\begin{tikzpicture}
\pie[before number =, after number = {\%},text=pin, ]{
    37.7/Investment Scams,
    21.1/{Dating \& Romance Scams},
    10.2/False Billing, 
    6.5/Threats,
    4.8/Online Shopping Scams,
    4.5/Remote Access Scams,
    3.1/Classified Scams,
    2.2/Health \& Medical Products,
    1.8/Identity Theft,
    1.2/Hacking,
    1.2/Phishing,
    1.0/Unexpected Prize \& Lottery,
    0.8/Inheritance Scams,
    0.7/Jobs and Employment Scams,
    0.6/Betting and Sports Investment Scams,
    2.4/Other Scams
    }
\end{tikzpicture}

\end{document}

答案1

正如评论中提到的,我不建议对大量类别使用饼图,因为饼图很快就会变得难以阅读。条形图可能是更好的选择,或者将小类别分组在一起。

但是,您可以通过修补/重新定义相关宏来调整的行为pgf-pie以稍微改善结果。请注意,对于这个答案,我使用了pgf-pieGithub 中的当前版本(https://github.com/pgf-tikz/pgf-pie,发布日期为 2020 年 12 月 26 日),比 CTAN 上的当前版本(2020 年 5 月 28 日)更新。这很重要,因为下面的补丁仅适用于 Github 版本(大概会在某个时候上传到 CTAN)。

第一个修改是从切片中删除较小值(低于 5%)的百分比。这是通过重新定义宏来实现的。\pgfpie@numbertext这是一个小宏,因此实际上不需要应用补丁,而是可以使用 重新定义完整的宏\def。这个想法是检查pgfmath参数是否大于 5,并使用\ifnum有条件地打印数字。请注意,\ifnum不能直接使用,因为\ifnum是整数比较,百分比可能是十进制数。

第二个修改是,对于值较小的切片,自动在标签后面添加百分比。这有点复杂,因为它需要\pgfpie@slice在两个地方修改,首先定义一个临时宏,根据值指定或不指定百分比,其次使用该宏作为切片标签,而不是参数#4。这由两个补丁完成,第一个补丁用于\pretocmd在开头定义标签\pgfpie@slice,然后是\patchcmd更改中间的标签打印代码\pgfpie@slice

注意,您也可以通过在调用中将百分比添加到相关标签来手动实现第二次修改的结果\pie

梅威瑟:

\documentclass[border=5mm]{standalone}
\usepackage{pgf-pie} % version: https://github.com/pgf-tikz/pgf-pie Dec 26, 2020
\usepackage{etoolbox}
\makeatletter
\pretocmd{\pgfpie@slice}{% define label text with percentages for small values
\pgfmathparse{#3 > 5}%
\ifnum\pgfmathresult=1 %
\def\txtlabel{#4}% original label for large values
\else%
\def\txtlabel{#4 (#3\%)}% label with percentage for small values
\fi%
}{\message{define label patch ok}}{\message{define label patch failed}}

\patchcmd{\pgfpie@slice}% use label text instead of original argument #4
{\pgfpie@text={\pgfpie@midangle:#4}}%
{\pgfpie@text={\pgfpie@midangle:\txtlabel}}%
{\message{add pct patch ok}}%
{\message{add pct patch failed}}%

\def\pgfpie@numbertext#1{% don't print percentage in slice for small values
  \pgfpie@ifhidenumber{}{%
    \pgfmathparse{#1 > 5}%
    \ifnum\pgfmathresult=1 %
    \pgfpie@beforenumber#1\pgfpie@afternumber%
    \fi
  }%
}
\makeatother
\begin{document}

\begin{tikzpicture}
\pie[before number =, after number = {\%},text=pin, ]{
    37.7/Investment Scams,
    21.1/{Dating \& Romance Scams},
    10.2/False Billing, 
    6.5/Threats,
    4.8/Online Shopping Scams,
    4.5/Remote Access Scams,
    3.1/Classified Scams,
    2.2/Health \& Medical Products,
    1.8/Identity Theft,
    1.2/Hacking,
    1.2/Phishing,
    1.0/Unexpected Prize \& Lottery,
    0.8/Inheritance Scams,
    0.7/Jobs and Employment Scams,
    0.6/Betting and Sports Investment Scams,
    2.4/Other Scams
    }
\end{tikzpicture}

\end{document}

结果:

在此处输入图片描述

问题要求inside为大值和pin小值添加标签。但是,在这个例子中,标签相当长,因此唯一可以放置标签的片段是投资骗局。因此我认为最好将所有标签都固定。当然,通过在 的其他地方应用相同的测试(使用\pgfmathparse\ifnum),也可以实现这样的修改\pgfpie@slice

相关内容