我正在尝试用 tikz 制作一个嵌套的环形图表,以显示最近使用 MEA 系统的研究中使用的不同细胞类型的百分比。外层分为两层:非神经元和神经元研究。我的内层按研究数量划分,包括神经元和非神经元细胞。我有以下问题:
- 是否可以将内圈与神经元细胞百分比和外圈细胞的“神经元”部分对齐(反之亦然)。如果有一个选项可以旋转内圈,那么对齐就很容易了。
- 我怎样才能使从内圆出发的线条从每个相应的黑点开始(就像在外圆中所做的那样)?
最后,如果您对我的图表的美观性有任何其他建议,请随时提供意见!我的代码(如下)是从此评论中分叉出来的这里。
感谢您的时间。
\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{fadings}
% POR AS PERCENTAGENS COMO NO LATEX DA QUESTAO !
\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 pt5
\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}
}
\newcommand{\innerchartthreed}\[1\]{
% Calculate total
\pgfmathsetmacro{\totalnum}{0}
\foreach \value/\colour/\name in {#1} {
\pgfmathparse{\value+\totalnum}
\global\let\totalnum=\pgfmathresult
}
\pgfmathsetmacro{\wheelwidth}{\outerradius-\innerradius}
\pgfmathsetmacro{\midradius}{(\outerradius+\innerradius)/2}
\begin{scope}\[rotate=90,xscale=0.6,yscale=1\]
\pgfmathsetmacro{\cumnum}{0}
\foreach \[count=\n\] \value/\colour/\name in {#1} {
\pgfmathsetmacro{\newcumnum}{\cumnum + \value/\totalnum*360}
\pgfmathsetmacro{\midangle}{-(\cumnum+\newcumnum)/2}
\filldraw\[draw=black,fill=\colour\] (-\cumnum:\outerradius) arc (-\cumnum:-(\newcumnum):\outerradius) --
(-\newcumnum:\innerradius) arc (-\newcumnum:-(\cumnum):\innerradius) -- cycle;
\fill\[transparent\] circle (\innerradius);
\draw node \[text=white, font=\bfseries\] (inner \n) at (\midangle:{\innerradius+\wheelwidth/2}) {\name};
\global\let\cumnum=\newcumnum
}
\end{scope}
}
\begin{document}
\begin{tikzpicture}
%\fill (1.8,-2.1) circle (.5mm);
\end{tikzpicture}
\definecolor{ao(english)}{rgb}{0.0, 0.5, 0.0}
\definecolor{azure(colorwheel)}{rgb}{0.0, 0.5, 1.0}
\definecolor{cardinal}{rgb}{0.77, 0.12, 0.23}
\definecolor{caribbeangreen}{rgb}{0.0, 0.8, 0.6}
\definecolor{carolinablue}{rgb}{0.6, 0.73, 0.89}
\begin{tikzpicture}
%\fill (0,0) circle (.5mm);
\piechartthreed\[scale=0.8,
background color=orange!50,
mix color=darkgray\]
{261/red,99/green}
\foreach \i in {1,...,2} { \fill (pc \i) circle (.8mm);}
\draw\[darkgray\] (pc 1) -- ++(-2.95,0.5) coordinate (s1) node\[anchor=south east\] {\Large{\textbf{Non-neuronal}}}
node\[anchor=north east\] {\Large{72.3\%}};
\draw\[darkgray\] (pc 2) -- (5.5,-2) coordinate(s2) node\[anchor=south west\] {\Large{\textbf{Neuronal}}}
node\[anchor=north west\] {\Large{45.5\%}};
%
%\draw\[darkgray\] (pc 3) -- ++(3,-1) coordinate (s3) node\[anchor=south west\] {Sector 3}
%% node\[anchor=north west\] {14\%};
%%
%\draw\[darkgray\] (pc 4) -- ++(3,0) coordinate (s4) node\[anchor=south west\] {Sector 4}
%% node\[anchor=north west\] {25\%};
%%
%\draw\[darkgray\] (pc 2) -- ++(3,-2) coordinate (s2) -- (s2 -| s4) node\[anchor=south west\] {Sector 5} node\[anchor=north west\] {17\%};
\def\innerradius{0.7cm}
\def\outerradius{1.75cm}
\pgfmathsetlengthmacro{\centerradius}{(\outerradius + \innerradius)/2}
\pgfmathsetlengthmacro{\donutcenter}{\innerradius/2}
% Clock-wise order, with cardiomyocyte:
%Non-neuronal (cardinal): cardiomyocite, fibroblast, hek-293, sh-sy5y,rbl-1
%Neuronal (green): cortex, hippocampus, ventricular, drg
\innerchartthreed{95/cardinal!95/,38/cardinal!60/,38/cardinal!50/,38/cardinal!40/,19/cardinal!40/,56/green!90/,38/green!70/,19/green!50/,19/green!50/}
\fill (inner 1) circle (.5mm);
\draw\[darkgray\] (inner 1.center) -- (4.2,1) node\[anchor=south west\] {Cardiomyocyte};
\fill (inner 2) circle (.5mm);
\draw\[darkgray\] (inner 2.center) -- (4.5,-.5) node\[anchor=west\] {Fibroblast};
\fill (inner 3) circle (.5mm);
\draw\[darkgray\] (inner 3.center) -- (3.5,-3) node\[anchor=west\] {HEK-293};
\fill (inner 4) circle (.5mm);
\draw\[darkgray\] (inner 4.center) -- (2,-3.9) node\[anchor=north\] {SH-SY5Y};
\fill (inner 4) circle (.5mm);
\draw\[darkgray\] (inner 4.center) -- (2,-3.9) node\[anchor=north\] {SH-SY5Y};
\fill (inner 5) circle (.5mm);
\draw\[darkgray\] (inner 5.center) -- (-1,-4.2) node\[anchor=north\] {RBL-1};
\fill (inner 6) circle (.5mm);
\draw\[darkgray\] (inner 6.center) -- (-3.5,-3.9) node\[anchor=north\] {Cortex};
\fill (inner 7) circle (.5mm);
\draw\[darkgray\] (inner 7.center) -- (-6.5,-0.6) node\[anchor=north\] {Hippocampus};
\fill (inner 8) circle (.5mm);
\draw\[darkgray\] (inner 8.center) -- (-1.85,3.2) node\[anchor=south east\] {Ventricular};
\fill (inner 9) circle (.5mm);
\draw\[darkgray\] (inner 9.center) -- (0,3.2) node\[anchor=south west\] {DRG};
\end{tikzpicture}
\end{document}
% TO-DO:
%Addendum: I also wanted the colors a bit more shiny. I was able to achieve this by adding pgfkeys for mix rate low and mix rate high and replace the values 20/5 in the code with \piechartthreedmixratehigh/\piechartthreedmixratelow. Then setting the high/low mix rates to 80/60 makes nice and shiny colors. You also need to replace the remaining occurence of gray in \col!20!gray with \piechartthreedmixcolor][2]][2]
[这是我提供的代码编译后的 .pdf 的样子][3]
最后编辑:如果有人感兴趣的话,这是我的最终图像:
答案1
我认为你正在寻找这样的东西:
为了实现这一点,我修改了\innerchartthreed
宏,现在它采用逗号分隔的四元组列表:数量、颜色、名称、偏移量。OP 中的数量加起来为 360,但实际上,代码会将适当的角度计算为这些数量总和的百分比,因此您可以使用原始数据来指定数量。
接下来,我更改了\innerchartthreed
宏,使其将名称添加到圆圈外部,并在每个段内添加一条线来标记。由于图片中的圆圈实际上是椭圆形,我看不出有什么简单的方法可以自动设置名称与中心的距离,因为与图表中心的距离会随着角度而变化,因此我添加了偏移量以将标签沿径向线进一步向外移动。此外,我添加了一个可选参数来\innerchartthreed
设置内圆相对于外圆盘的起始角度。这允许您调整内圆以匹配外圆(奇怪的是,调整应该是 228,但我发现 222 看起来更好)。
最终结果是,带有标签的内盘由以下方式绘制:
\innerchartthreed[222]{% amount/colour/name/label offset
95/cardinal!95/Cardiomyocyte/1.2,
38/cardinal!60/Fibroblast/0.2,
38/cardinal!50/HEK-293/0,
38/cardinal!40/SH-SY5Y/0.5,
19/cardinal!40/RBL-1/0.5,
56/green!90/Cortex/1,
38/green!70/Hippocampus/1.8,
19/green!50/Ventricular/1.8,
19/green!50/DRG/1.5
}
之后,我又做了一些类似的调整,以便 \piechartthreed
放置外圆标签。带标签的外圆盘不是由以下人员绘制的:
% amount/color/name
\piechartthreed[scale=0.8, background color=orange!50, mix color=darkgray]{
228/red/Non-neuronal\\72.3\%,
132/green/Neuronal\\45.5\%
}
当然,我只是破解了问题中的代码,正如 OP 所说,大部分艰苦的工作都是由 Alain Matthes 在他的精彩回答中完成的如何使用 pgf-plot 设计 3D 甜甜圈饼图?。
哦,楼主SH-SY5
输入了两次标签,所以我删除了一个。不确定 72.3% 和 45.5%,但我没有更改这个。
以下是更新后的代码:
\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/\name [count=\xi] in {#2}{%
\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 pt5
\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
\node (\piechartthreedname\xi) at (\totan+2*\an/3:0.75cm){$\bullet$};
\node[align=center] (\piechartthreedname label\xi) at (\totan+2*\an/3:1.75cm) {\Large\name};
\draw[darkgray](\piechartthreedname\xi.center)--(\piechartthreedname label\xi);
\pgfmathsetmacro\totan{\totan+\an} \global\let\totan\totan
}
\end{scope}
\draw[thin,black](0,0) circle (0.5cm);
\end{scope}
\end{scope}
}
\newcommand{\innerchartthreed}[2][0]{
% Calculate total
\pgfmathsetmacro{\totalnum}{0}
\foreach \value/\colour/\name/\offset in {#2} {
\pgfmathparse{\value+\totalnum}
\global\let\totalnum=\pgfmathresult
}
\pgfmathsetmacro{\wheelwidth}{\outerradius-\innerradius}
\pgfmathsetmacro{\midradius}{(\outerradius+\innerradius)/2}
\begin{scope}[rotate=90,xscale=0.6,yscale=1]
\pgfmathsetmacro{\cumnum}{#1}
\foreach [count=\n] \value/\colour/\name/\offset in {#2} {
\pgfmathsetmacro{\newcumnum}{\cumnum + \value/\totalnum*360}
\pgfmathsetmacro{\midangle}{Mod(-(\cumnum+\newcumnum)/2, 360)}
\filldraw[draw=black,fill=\colour] (-\cumnum:\outerradius) arc (-\cumnum:-(\newcumnum):\outerradius) --
(-\newcumnum:\innerradius) arc (-\newcumnum:-(\cumnum):\innerradius) -- cycle;
\draw node [text=black, font=\bfseries] (inner \n) at (\midangle:{\innerradius+\wheelwidth/2}) {$\bullet$};
\node (inner label \n) at (\midangle:{5+\offset}) {\name};
\draw[darkgray] (inner \n.center) -- (inner label \n);
\global\let\cumnum=\newcumnum
}
\fill[transparent] circle (\innerradius);
\end{scope}
}
\begin{document}
\definecolor{ao(english)}{rgb}{0.0, 0.5, 0.0}
\definecolor{azure(colorwheel)}{rgb}{0.0, 0.5, 1.0}
\definecolor{cardinal}{rgb}{0.77, 0.12, 0.23}
\definecolor{caribbeangreen}{rgb}{0.0, 0.8, 0.6}
\definecolor{carolinablue}{rgb}{0.6, 0.73, 0.89}
\def\innerradius{0.7cm}
\def\outerradius{1.75cm}
\pgfmathsetlengthmacro{\centerradius}{(\outerradius + \innerradius)/2}
\pgfmathsetlengthmacro{\donutcenter}{\innerradius/2}
\begin{tikzpicture}
% amount/color/name
\piechartthreed[scale=0.8, background color=orange!50, mix color=darkgray]{
228/red/Non-neuronal\\72.3\%,
132/green/Neuronal\\45.5\%
}
% Clock-wise order, with cardiomyocyte:
% Non-neuronal (cardinal): cardiomyocite, fibroblast, hek-293, sh-sy5y,rbl-1
% Neuronal (green): cortex, hippocampus, ventricular, drg
% amount/colour/name/label offset
\innerchartthreed[222]{
95/cardinal!95/Cardiomyocyte/1.2,
38/cardinal!60/Fibroblast/0.2,
38/cardinal!50/HEK-293/0,
38/cardinal!40/SH-SY5Y/0.5,
19/cardinal!40/RBL-1/0.5,
56/green!90/Cortex/1,
38/green!70/Hippocampus/1.8,
19/green!50/Ventricular/1.8,
19/green!50/DRG/1.5
}
\end{tikzpicture}
\end{document}