如何使用 pgf-plot 设计 3D 甜甜圈饼图?

如何使用 pgf-plot 设计 3D 甜甜圈饼图?

似乎pgfplots用户不喜欢饼图,但有时我们又不得不用(出于某些原因)。所以我想知道是否有办法制作所谓的环形图。

例如这样的:

甜甜圈的图像

答案1

和 T. Tantau 和 Mark S. Everitt 一样,我认为这样做不好。我不明白您是否想使用 pgfplots 或 pgf plots?它们不是完全相同的东西。如果yshift阴影是根据图片高度计算的,代码会更好。

更新 2

一些修正,完成并清理代码。

在此处输入图片描述

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{fadings}

\begin{document}
\begin{tikzpicture}[fading style/.style={preaction={fill=#1,opacity=.8,
                   path fading=circle with fuzzy edge 20 percent}}]

  \begin{scope}[xscale=5,yscale=3]
    \path[fading style=black,transform canvas={yshift=-40pt}] (0,0) circle (1cm);         
    \fill[gray](0,0) circle (0.5cm);  
    \path[fading style=white,transform canvas={yshift=-16mm}] (0,0) circle (0.65cm);    
    \draw[yshift=-3mm](0,0) circle (0.5cm); 

    \shadedraw[top color=green!20!gray,,bottom color=green!5!black,draw=black,very thin]  
        (90:0.5cm)--++(0,-3mm) arc(90:-5:0.5cm)--++(0,3mm)  arc(-5:90:0.5cm)--cycle;      
    \shadedraw[top color=orange!20!gray,bottom color=orange!5!black,draw=black,very thin]   
        (-105:0.5cm)--++(0,-3mm) arc(-105:-225 :0.5cm)--++(0,3mm)  arc(-225:-105:0.5cm)--cycle;   
    \shadedraw[top color=blue!50!white,,bottom color=blue!5!black,draw=black,very thin]   
        (135 :0.5cm)--++(0,-3mm) arc(135:90:0.5cm)--++(0,3mm)  arc(90:135:0.5cm)--cycle;  

    \begin{scope}[draw=black,thin]
       \fill[green!20!gray](90 :0.5cm)--(90:1cm) arc(90:-5:1cm)--(-5:0.5cm) arc(-5:90 :0.5cm);     
       \fill[white!20!gray](-5 :0.5cm)--(-5:1cm) arc(-5:-105 :1cm)--(-105:0.5cm) arc(-105:-5:0.5cm);        
       \fill[orange!20!gray](-105:0.5cm)--(-105:1cm) arc(-105:-225 :1cm)--(-225:0.5cm) arc(-225:-105:0.5cm);
       \fill[blue!50!white](135:0.5cm)--(135 :1cm) arc(135:90:1cm)--(90:0.5cm) arc(90:135:0.5cm);
    \end{scope}
    \draw[thin,black](0,0) circle (0.5cm);   

    \shadedraw[bottom color=orange!20!gray,top color=orange!5!black,draw=black,very thin]   
    (-180:1cm) --++(0,-3mm) arc (-180:-105 :1cm) -- ++(0,3mm)  arc (-105 :-180  :1cm) -- cycle;  
    \shadedraw[bottom color=white!20!gray,top color=white!5!black,draw=black,very thin]   
    (-105:1cm) --++(0,-3mm) arc (-105:0 :1cm) -- ++(0,3mm)  arc (0 :-105  :1cm) -- cycle;  

      \draw[very thin] (90:0.5cm) -- (90:1cm)
            (-5:0.5cm) -- (-5:1cm)
            (-105:0.5cm) -- (-105:1cm)
            (135:0.5cm) -- (135 :1cm)
            (0,0) circle (1cm)
            (90:0.5cm)  arc (90 :135:0.5cm);

    \coordinate (left border) at (1.5cm,0cm); 
    \coordinate (right border) at (-1.5cm,0cm); 
    \coordinate (l1) at (43.5:0.75 cm);
    \coordinate (l2) at (-55:0.75 cm); 
    \coordinate (l3) at (117.5:0.75 cm);
    \coordinate (l4) at (-160:0.75 cm);

    \begin{scope}[lab/.style={gray!50!black,thick,draw}]
        \fill[lab] (l1) circle(.4mm) -- (l1-| left border) node[anchor=south east] {Corporate}
                                                           node[anchor=north east] {26\%};         
       \fill[lab] (l2) circle(.4mm) -- (l2-| left border)  node[anchor=south east] {Plastique}
                                                           node[anchor=north east] {28\%}; 
       \fill[lab] (l3) circle(.4mm) -- (l3-| right border) node[anchor=south west] {Rhodia}
                                                           node[anchor=north west] {12.5\%};         
       \fill[lab] (l4) circle(.4mm) -- (l4-| right border) node[anchor=south west] {Chimique}
                                                           node[anchor=north west] {43.5\%}; 
    \end{scope}
   \end{scope}  
\end{tikzpicture}    
\end{document}        

尝试自动化版本 4

\piechartthreed

选项 #2 角度和颜色列表的两个参数 #1(a1/col1,a2/col2,etc...)

选项scale缩放饼图,mix color用于为扇区着色,background color用于为背景着色,name用于命名每个扇区“中心”的点。

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{fadings}

\pgfkeys{%
/piechartthreed/.cd,
scale/.code                =  {\def\piechartthreedscale{#1}},
mix color/.code            =  {\def\piechartthreedmixcolor{#1}},
background color/.code     =  {\def\piechartthreedbackcolor{#1}},
name/.code                 =  {\def\piechartthreedname{#1}}}

 \newcommand\piechartthreed[2][]{% 
   \pgfkeys{/piechartthreed/.cd,
     scale            = 1,
     mix color        = gray,
     background color = white,
     name             = pc} 
  \pgfqkeys{/piechartthreed}{#1}
  \begin{scope}[scale=\piechartthreedscale] 
  \begin{scope}[xscale=5,yscale=3] 
     \path[preaction={fill=black,opacity=.8,
         path fading=circle with fuzzy edge 20 percent,
         transform canvas={yshift=-15mm*\piechartthreedscale}}] (0,0) circle (1cm);
    \fill[gray](0,0) circle (0.5cm);  
     \path[preaction={fill=\piechartthreedbackcolor,opacity=.8,
          path fading=circle with fuzzy edge 20 percent,
          transform canvas={yshift=-10mm*\piechartthreedscale}}] (0,0) circle (0.5cm);
     \pgfmathsetmacro\totan{0} 
     \global\let\totan\totan 
     \pgfmathsetmacro\bottoman{180} \global\let\bottoman\bottoman 
     \pgfmathsetmacro\toptoman{0}   \global\let\toptoman\toptoman 
     \begin{scope}[draw=black,thin]
     \foreach \an/\col [count=\xi] in {#2}{%
     \def\space{ } 
        \coordinate (\piechartthreedname\space\xi) at (\totan+\an/2:0.75cm); 
        \ifdim 180pt>\totan pt 
         \ifdim 0pt=\toptoman pt
            \shadedraw[left color=\col!20!\piechartthreedmixcolor,
                       right color=\col!5!\piechartthreedmixcolor,
                       draw=black,very thin] (0:.5cm) -- ++(0,-3mm) arc (0:\totan+\an:.5cm) 
                                                       -- ++(0,3mm)  arc (\totan+\an:0:.5cm);
            \pgfmathsetmacro\toptoman{180} 
            \global\let\toptoman\toptoman         
            \else
            \shadedraw[left color=\col!20!\piechartthreedmixcolor,
                       right color=\col!5!\piechartthreedmixcolor,
                       draw=black,very thin](\totan:.5cm)-- ++(0,-3mm) arc(\totan:\totan+\an:.5cm)
                                                        -- ++(0,3mm)  arc(\totan+\an:\totan:.5cm); 
          \fi
        \fi   
        \fill[\col!20!gray,draw=black] (\totan:0.5cm)--(\totan:1cm)  arc(\totan:\totan+\an:1cm)
                                     --(\totan+\an:0.5cm) arc(\totan+\an:\totan :0.5cm);     
       \pgfmathsetmacro\finan{\totan+\an}
       \ifdim 180pt<\finan pt 
         \ifdim 180pt=\bottoman pt
            \shadedraw[left color=\col!20!\piechartthreedmixcolor,
                       right color=\col!5!\piechartthreedmixcolor,
                       draw=black,very thin] (180:1cm) -- ++(0,-3mm) arc (180:\totan+\an:1cm) 
                                                       -- ++(0,3mm)  arc (\totan+\an:180:1cm);
            \pgfmathsetmacro\bottoman{0}
            \global\let\bottoman\bottoman
            \else
            \shadedraw[left color=\col!20!\piechartthreedmixcolor,
                       right color=\col!5!\piechartthreedmixcolor,
                       draw=black,very thin](\totan:1cm)-- ++(0,-3mm) arc(\totan:\totan+\an:1cm)
                                                        -- ++(0,3mm)  arc(\totan+\an:\totan:1cm); 
          \fi
        \fi
        \pgfmathsetmacro\totan{\totan+\an}  \global\let\totan\totan 
       } 
    \end{scope}
    \draw[thin,black](0,0) circle (0.5cm);
   \end{scope}  
\end{scope}
}

\begin{document} 
 \pagecolor{orange!50}
 \begin{tikzpicture}
   \piechartthreed[scale=0.8,
                   background color=orange!50,
                   mix color= darkgray]
                   {40/green,60/blue,90/red,50/orange,120/yellow}
   \foreach \i in {1,...,5} { \fill (pc \i) circle (.5mm);}
   \draw[darkgray] (pc 1)  -- ++(4,0) coordinate (s1) node[anchor=south east] {Sector 1}
                                                      node[anchor=north east] {11\%};
   \draw[darkgray] (pc 5)  -- (pc 5 -| s1) node[anchor=south east] {Sector 5}
                                                      node[anchor=north east] {33\%}; 
   \draw[darkgray] (pc 2)  -- ++(1,1) coordinate (s2) -- (s2 -| s1) node[anchor=south east] {Sector 2}
                                                      node[anchor=north east] {17\%}; 
   \draw[darkgray] (pc 3)  -- ++(-4,0) coordinate (s3) node[anchor=south west] {Sector 3}
                                                      node[anchor=north west] {14\%};
   \draw[darkgray] (pc 4)  -- ++(-1,-1) coordinate (s4) --(s4 -| s3) node[anchor=south west] {Sector 4}
                                                      node[anchor=north west] {25\%};
 \end{tikzpicture}

\end{document}

在此处输入图片描述

去做

清理代码并添加一些选项。

答案2

xelatex用或运行latex->dvips->ps2pdf

\documentclass{article}
\usepackage[dvipsnames,svgnames]{pstricks}
\usepackage{pst-solides3d}

\begin{document}
\begin{pspicture}(-3.5,-1.5)(3.5,1.5)
\psset[pst-solides3d]{viewpoint=50 20 20 rtp2xyz,
  Decran=20}
\psSolid[object=anneau,h=1,R=8,r=6,ngrid=90,grid=false,
  fcol= 0 1  19 { (Red) } for 
       20 1  59 { (LimeGreen) } for 
       60 1 179 { (Blue) } for 
      180 1 299 { (Sepia) } for 
      300 1 359 { (BrickRed) } for 
  ](0,0,0)
\end{pspicture}
\end{document}

在此处输入图片描述

或者使用网格线:

\documentclass{article}
\usepackage[dvipsnames,svgnames]{pstricks}
\usepackage{pst-solides3d}

\begin{document}
\begin{pspicture}(-3.5,-1.5)(3.5,1.5)
\psset[pst-solides3d]{viewpoint=50 20 20 rtp2xyz,
  Decran=20}
\psSolid[object=anneau,h=1,R=8,r=6,ngrid=90,linewidth=0.1pt,
  fcol= 0 1  19 { (Red) } for 
       20 1  59 { (LimeGreen) } for 
       60 1 179 { (Blue) } for 
      180 1 299 { (Sepia) } for 
      300 1 359 { (BrickRed) } for 
  ](0,0,0)
\end{pspicture}
\end{document}

在此处输入图片描述

答案3

这是第一个版本。到目前为止,您只能定义各个扇区的角度。每个扇区的中心都有一个节点n(扇区号)您可以用它进行标记。

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc}

\global\edef\lastangle{0}
\newcounter{sectornumber}

\newcommand{\ring}[1]{% angles
\setcounter{sectornumber}{1}
\foreach \x in {#1}
{   \pgfmathsetmacro{\na}{\lastangle+\x}
    \fill[red,draw=black] (\lastangle:3) arc (\lastangle:\na:3) -- ++(0,0,0.5) arc (\na:\lastangle:3) -- cycle;
    \fill[blue,draw=black] (\lastangle:4) arc (\lastangle:\na:4) -- ++(0,0,0.5) arc (\na:\lastangle:4) -- cycle;
    \global\edef\lastangle{\na}
}
\global\edef\lastangle{0}
\foreach \x in {#1}
{   \pgfmathsetmacro{\na}{\lastangle+\x}
    \fill[green,draw=black] (0,0,0.5) ++(\lastangle:3) arc (\lastangle:\na:3) -- ++(\na:1) arc (\na:\lastangle:4) -- cycle;
    \node (n\thesectornumber) at ($(0,0,0.5)+(\lastangle+\x/2:3.5)$) {};
    \stepcounter{sectornumber}
    \global\edef\lastangle{\na}
}
}

\begin{document}

\begin{tikzpicture}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
\ring{10,20,30,40,50,60,70,80}
\draw[thick] (n1) -- ++(5:2) node[above right] {Bla 1};
\draw[thick] (n3) -- ++(45:2) node[above] {Bla 2};
\draw[thick] (n6) -- ++(180:2) node[left] {Bla 3};
\draw[thick] (n8) -- ++(-45:2) node[right] {Bla 4};
\end{tikzpicture}

\end{document}

在此处输入图片描述


编辑1:修订版,具有可选颜色和阴影边缘。它仅适用于相当扁平的戒指:

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc,shapes,shadows}

\global\edef\lastangle{0}
\newcounter{sectornumber}

\newcommand{\ring}[4]{% angles&colors, inner, outer radius, height
\begin{scope}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
\global\edef\lastangle{0}
\setcounter{sectornumber}{1}
\foreach \x/\ringcolor in {#1}
{   \pgfmathsetmacro{\na}{\lastangle+\x*3.6}
    \colorlet{darkercolor}{\ringcolor!60!black}
    \colorlet{darkestcolor}{\ringcolor!20!black}
    \shadedraw[top color=darkercolor,bottom color=darkestcolor,draw=darkercolor] (\lastangle:#2) arc (\lastangle:\na:#2) -- ++(0,0,#4) arc (\na:\lastangle:#2) -- cycle;
    \shadedraw[top color=darkercolor,bottom color=darkestcolor,draw=darkercolor] (\lastangle:#3) arc (\lastangle:\na:#3) -- ++(0,0,#4) arc (\na:\lastangle:#3) -- cycle;
    \global\edef\lastangle{\na}
}
\global\edef\lastangle{0}
\foreach \x/\ringcolor in {#1}
{   \pgfmathsetmacro{\na}{\lastangle+\x*3.6}
    \colorlet{darkercolor}{\ringcolor!60!black}
    \colorlet{darkestcolor}{\ringcolor!20!black}
    \fill[\ringcolor,draw=darkercolor] (0,0,#4) ++(\lastangle:#2) arc (\lastangle:\na:#2) -- ++(\na:#3-#2) arc (\na:\lastangle:#3) -- cycle;
    \pgfmathsetmacro{\nodepos}{(#3+#2)*0.5}
    \node (n\thesectornumber) at ($(0,0,#4)+(\lastangle+\x*1.8:\nodepos)$) {};
    \stepcounter{sectornumber}
    \global\edef\lastangle{\na}
}
\end{scope}
}

\begin{document}

\begin{tikzpicture}
\ring{5/red!80!gray,15/blue!80!gray,15/yellow!80!gray,25/green!80!gray,10/orange!80!gray,10/violet!80!gray,5/brown!80!gray,15/cyan!80!gray}{3}{4}{0.5}
\foreach \x/\label in {1/Kill Bill,2/The Godfather,3/Garden State,4/Sin City,5/Fight Club,6/Star Trek VI,7/Terminator 2,8/Gran Torino}
{   \draw[thick] (n\x) -- ++(0,0.5) node[fill=white,draw,rounded rectangle,inner sep=2pt,thin,fill opacity=0.7,text opacity=1] {\tiny\label};
}
\end{tikzpicture}

\begin{tikzpicture}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
\ring{5/red!80!gray,15/blue!80!gray,15/yellow!80!gray,25/green!80!gray,10/orange!80!gray,10/violet!80!gray,5/brown!80!gray,15/cyan!80!gray}{2}{4}{2}
\foreach \x/\label in {1/Kill Bill,2/The Godfather,3/Garden State,4/Sin City,5/Fight Club,6/Star Trek VI,7/Terminator 2,8/Gran Torino}
{   \draw[thick] (n\x) -- ++(0.5,0.5) node[fill=white,draw,rounded rectangle,inner sep=2pt,thin,fill opacity=0.7,text opacity=1] {\tiny\label};
}
\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容