群组图饼图

群组图饼图

有没有办法使用 groupplots 对饼图进行分组?我想要类似这样的效果: 在此处输入图片描述

以下是 MWE:

\documentclass[times]{article}
\usepackage{pgfplots, pgfplotstable}
\usepackage{tikz}
\usepgfplotslibrary{groupplots}
\begin{document}
\newcommand{\legend}[2][]{
 \begin{scope}[#1]
 \path
    \foreach \n/\s in {#2}
        {
              ++(0,-10pt) node[\s,legend box] {} +(5pt,0) node[legend label] {\n}
        }
;
\end{scope}
}
\tikzstyle{chart}=[
legend label/.style={font={\scriptsize},anchor=west,align=left},
legend box/.style={rectangle, draw, minimum size=5pt},
axis/.style={black,semithick,->},
axis label/.style={anchor=east,font={\tiny}},
]
\tikzstyle{pie chart}=[
chart,
slice/.style={line cap=round, line join=round, very thick,draw=white},
pie title/.style={font={\bf}},
slice type/.style 2 args={
    ##1/.style={fill=##2},
    values of ##1/.style={}
}
]
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\newcommand{\pie}[3][]{
\begin{scope}[#1]
\pgfmathsetmacro{\curA}{90}
\pgfmathsetmacro{\r}{1}
\def\c{(0,0)}
\node[pie title] at (90:1.3) {#2};
\foreach \v/\s in{#3}{
    \pgfmathsetmacro{\deltaA}{\v/100*360}
    \pgfmathsetmacro{\nextA}{\curA + \deltaA}
    \pgfmathsetmacro{\midA}{(\curA+\nextA)/2}

    \path[slice,\s] \c
        -- +(\curA:\r)
        arc (\curA:\nextA:\r)
        -- cycle;
    \pgfmathsetmacro{\d}{max((\deltaA * -(.4/50) + 1) , .5)}

    \begin{pgfonlayer}{foreground}
    \path \c -- node[pos=\d,pie values,values of \s]{$\v\%$} +(\midA:\r);
    \end{pgfonlayer}

    \global\let\curA\nextA
}
\end{scope}
}
\begin{figure}
\begin{tikzpicture}
[
pie chart,
slice type={inlined}{lightgray},
slice type={noninlined}{darkgray},
pie values/.style={font={\tiny}},
scale=1
]

\pie{\footnotesize{benchmark}}{41/inlined,13/noninlined}

\legend[shift={(-1cm,-1cm)}]{{Inlined}/inlined, {Not inlined}/noninlined}
\end{tikzpicture}
\end{figure}
  \end{document}

答案1

要放置饼图,您可以使用\subcaptionbox(来自subcaption包);可以借助新命令 来缩短饼图包含的代码;使用a 中的\putpie两个s ,您可以将图例放置在所需的位置:minipage\makebox

\documentclass{article}
\usepackage{pgfplots, pgfplotstable}
\usepackage{subcaption}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=newest}

\newcommand{\legend}[2][]{
 \begin{scope}[#1]
 \path
    \foreach \n/\s in {#2}
        {
              ++(0,-10pt) node[\s,legend box] {} +(5pt,0) node[legend label] {\n}
        }
;
\end{scope}
}

\tikzset{
chart/.style={
  legend label/.style={font={\scriptsize},anchor=west,align=left},
  legend box/.style={rectangle, draw, minimum size=5pt},
  axis/.style={black,semithick,->},
  axis label/.style={anchor=east,font={\tiny}},
  },
pie chart/.style={
  chart,
  slice/.style={line cap=round, line join=round, very thick,draw=white},
  pie title/.style={font={\bfseries}},
  slice type/.style 2 args={
    ##1/.style={fill=##2},
    values of ##1/.style={}
    }
  }
}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\newcommand{\pie}[3][]{
\begin{scope}[#1]
\pgfmathsetmacro{\curA}{90}
\pgfmathsetmacro{\r}{1}
\def\c{(0,0)}
\node[pie title] at (90:1.3) {#2};
\foreach \v/\s in{#3}{
    \pgfmathsetmacro{\deltaA}{\v/100*360}
    \pgfmathsetmacro{\nextA}{\curA + \deltaA}
    \pgfmathsetmacro{\midA}{(\curA+\nextA)/2}

    \path[slice,\s] \c
        -- +(\curA:\r)
        arc (\curA:\nextA:\r)
        -- cycle;
    \pgfmathsetmacro{\d}{max((\deltaA * -(.4/50) + 1) , .5)}

    \begin{pgfonlayer}{foreground}
    \path \c -- node[pos=\d,pie values,values of \s]{$\v\%$} +(\midA:\r);
    \end{pgfonlayer}

    \global\let\curA\nextA
}
\end{scope}
}

\newcommand\putpie[1]{%
\subcaptionbox{}{%
  \begin{tikzpicture}
  #1
  \end{tikzpicture}}%
}

\begin{document}

\begin{figure}
\tikzset{every picture/.style={
  pie chart,
  slice type={inlined}{lightgray},
  slice type={noninlined}{darkgray},
  pie values/.style={font={\tiny}},
  scale=1
  }
}
\pgfplotsset{legend style={
  anchor=north,
  legend columns=2,
  cells={anchor=west},
  font=\footnotesize,
  rounded corners=2pt,
  },
}
\captionsetup[subfigure]{labelformat=empty}% to suppress the labels from captions
\makebox[\linewidth][l]{%
\begin{minipage}{\linewidth}
\centering
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\\
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\\
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}\hfill
\putpie{\pie{{\footnotesize benchmark}}{41/inlined,13/noninlined}}
\end{minipage}\quad
\begin{minipage}{3cm}
\raggedleft
\begin{tikzpicture}[remember picture]
\legend{{Inlined}/inlined, {Not inlined}/noninlined}
\end{tikzpicture}%
\end{minipage}}
\end{figure}

\end{document}

在此处输入图片描述

为了更好地控制各种图表的垂直对齐,最好使用环境subfigure;此外,现在图表的标题已委托给\putpie使用\caption,可以使用一行\putpie带有空内容的命令来为每一列生成标题:

\documentclass{article}
\usepackage{pgfplots, pgfplotstable}
\usepackage{subcaption}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=newest}

\newcommand{\legend}[2][]{
 \begin{scope}[#1]
 \path
    \foreach \n/\s in {#2}
        {
              ++(0,-10pt) node[\s,legend box] {} +(5pt,0) node[legend label] {\n}
        }
;
\end{scope}
}

\tikzset{
chart/.style={
  legend label/.style={font={\scriptsize},anchor=west,align=left},
  legend box/.style={rectangle, draw, minimum size=5pt},
  axis/.style={black,semithick,->},
  axis label/.style={anchor=east,font={\tiny}},
  },
pie chart/.style={
  chart,
  slice/.style={line cap=round, line join=round, very thick,draw=white},
  pie title/.style={font={\bfseries}},
  slice type/.style 2 args={
    ##1/.style={fill=##2},
    values of ##1/.style={}
    }
  }
}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\newcommand{\pie}[3][]{
\begin{scope}[#1]
\pgfmathsetmacro{\curA}{90}
\pgfmathsetmacro{\r}{1}
\def\c{(0,0)}
\foreach \v/\s in{#3}{
    \pgfmathsetmacro{\deltaA}{\v/100*360}
    \pgfmathsetmacro{\nextA}{\curA + \deltaA}
    \pgfmathsetmacro{\midA}{(\curA+\nextA)/2}

    \path[slice,\s] \c
        -- +(\curA:\r)
        arc (\curA:\nextA:\r)
        -- cycle;
    \pgfmathsetmacro{\d}{max((\deltaA * -(.4/50) + 1) , .5)}

    \begin{pgfonlayer}{foreground}
    \path \c -- node[pos=\d,pie values,values of \s]{$\v\%$} +(\midA:\r);
    \end{pgfonlayer}

    \global\let\curA\nextA
}
\end{scope}
}

\newlength\PieWd
\setlength\PieWd{2.2cm}
\newcommand\putpie[2]{%
\begin{subfigure}[t]{\PieWd}
  \centering
  \caption{#2}
  \begin{tikzpicture}
  #1
  \end{tikzpicture}%
\end{subfigure}%
}


\begin{document}

\begin{figure}
\tikzset{every picture/.style={
  pie chart,
  slice type={inlined}{lightgray},
  slice type={noninlined}{darkgray},
  pie values/.style={font={\tiny}},
  scale=1
  }
}
\pgfplotsset{legend style={
  anchor=north,
  legend columns=2,
  cells={anchor=west},
  font=\footnotesize,
  rounded corners=2pt,
  },
}
\captionsetup[subfigure]{labelformat=empty,textfont=bf}% to suppress the labels from captions and place the name in bold-face
\makebox[\linewidth][l]{%
\begin{minipage}{\linewidth}
\centering
\putpie{}{Column1}\hfill
\putpie{}{Column2}\hfill
\putpie{}{Column3}\hfill
\putpie{}{Column4}\hfill
\putpie{}{Column5}\\
\putpie{\pie{}{41/inlined,13/noninlined}}{benchmark}\hfill
\putpie{\pie{}{12/inlined,78/noninlined}}{some}\hfill
\putpie{\pie{}{9/inlined,35/noninlined}}{other}\hfill
\putpie{\pie{}{71/inlined,8/noninlined}}{title}\hfill
\putpie{\pie{}{47/inlined,14/noninlined}}{benchmark}\\[2ex]
\putpie{\pie{}{34/inlined,34/noninlined}}{perhaps}\hfill
\putpie{\pie{}{4/inlined,65/noninlined}}{different}\hfill
\putpie{\pie{}{23/inlined,32/noninlined}}{words}\hfill
\putpie{\pie{}{17/inlined,13/noninlined}}{benchmark}\hfill
\putpie{\pie{}{34/inlined,13/noninlined}}{benchmark}\\[2ex]
\putpie{\pie{}{50/inlined,50/noninlined}}{title2}\hfill
\putpie{\pie{}{21/inlined,12/noninlined}}{benchmark}\hfill
\putpie{\pie{}{34/inlined,43/noninlined}}{and}\hfill
\putpie{\pie{}{43/inlined,11/noninlined}}{other}\hfill
\putpie{\pie{}{66/inlined,22/noninlined}}{word}
\end{minipage}\quad
\begin{minipage}{3cm}
\raggedleft
\begin{tikzpicture}[remember picture]
\legend{{Inlined}/inlined, {Not inlined}/noninlined}
\end{tikzpicture}%
\end{minipage}}
\end{figure}

\end{document}

在此处输入图片描述

顺便说一句,我从弃用改为\tikzstyle\tikzset此外,\footnotesize不是带有参数的命令,而是字体开关,因此必须用作{\footnotesize text}(括号是为了保持局部效果,并且\par必须在离开长段落文本组之前添加。)

相关内容