我正在制作一个节点树,但我希望节点填充不同的形状,我想知道这是否可能?
现在我的树看起来像这样
但我希望每个节点都像这样
黄色、红色和绿色区域的大小由损失的大小决定。
我目前拥有的树的代码如下:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\title{Tree, loss}
\date{October 2020}
\usepackage{natbib}
\usepackage{graphicx}
\begin{document}
\maketitle
\tikzstyle{treenode0} = [circle, draw=black, fill=yellow!20, align=center]
\tikzstyle{treenode1} = [circle, draw=black, fill=red!20, align=center]
\tikzstyle{treenode2} = [circle, draw=black, fill=green!10, align=center]
\scalebox{0.75}{
\begin{tikzpicture}[node distance=2.2cm]
%n=4, alpha=0.02
%checking how it will be with more nodes
\node[treenode2] (node0) {Loss0: 0.500 \\ Loss1: 0.500 \\ Loss2: 0.045} ;
\node[treenode2, below of=node0, left of = node0] (node1a) {Loss0: 0.125 \\ Loss1: 0.875 \\ Loss2: 0.025};
\node[treenode2, below of=node0, right of = node0] (node1b) {Loss0: 0.875 \\ Loss1: 0.125 \\ Loss2: 0.025};
\draw[->] (node0) -- (node1a);
\draw[->] (node0) -- (node1b);
\node[treenode0, below of=node1a, left of = node1a] (node2a) {Loss0: 0.875 \\ Loss1: 0.125 \\ Loss2: 0.025};
\node[treenode2, below of=node1a, right of = node1a] (node2b) {Loss0: 0.500 \\ Loss1: 0.500 \\ Loss2: 0.020};
\node[treenode1, below of=node1b, right of = node1b] (node2c) {Loss0: 1.000 \\ Loss1: 0.000 \\ Loss2: 0.020};
\draw[->] (node1a) -- (node2a);
\draw[->] (node1a) -- (node2b);
\draw[->] (node1b) -- (node2b);
\draw[->] (node1b) -- (node2c);
\node[treenode0, below of=node2a, left of=node2a] (node3a) {Loss0: 0.000 \\ Loss1: 1.000 \\ Loss2: 0.020};
\node[treenode0, below of=node2a, right of=node2a] (node3b) {Loss0: 0.000 \\ Loss1: 1.000 \\ Loss2: 0.020};
\node[treenode1, below of=node2b, right of=node2b] (node3c) {Loss0: 1.000 \\ Loss1: 0.000 \\ Loss2: 0.020};
\node[treenode1, below of=node2c, right of=node2c] (node3d) {Loss0: 1.000 \\ Loss1: 0.000 \\ Loss2: 0.020};
\draw[->] (node2a) -- (node3a);
\draw[->] (node2a) -- (node3b);
\draw[->] (node2b) -- (node3b);
\draw[->] (node2b) -- (node3c);
\draw[->] (node2c) -- (node3c);
\draw[->] (node2c) -- (node3d);
\node[treenode0, below of=node1a, left of = node3a] (node4a) {Loss0: 0.875 \\ Loss1: 0.125 \\ Loss2: 0.025};
%\node[treenode2, below of=node1a, right of = node1a] (node4b) {Loss0: 0.500 \\ Loss1: 0.500 \\ Loss2: 0.020};
\node[treenode1, below of=node3d, right of = node3d] (node4c) {Loss0: 1.000 \\ Loss1: 0.000 \\ Loss2: 0.020};
\end{tikzpicture}
}
\end{document}
该节点的代码如下:
\begin{tikzpicture}
[node0/.pic={
\fill[fill=green!20] (0,0) -- (3cm,0cm) arc [start angle=0, end angle=30, radius=3cm] -- cycle;
\fill[fill=red!20] (0,0) -- (2.598cm,1.5cm) arc [start angle=30, end angle=200, radius=3cm] -- cycle;
\fill[fill=yellow!30] (0,0) -- (-2.814cm,-1.026cm) arc [start angle=200, end angle = 360, radius=3cm] -- cycle;
\draw[color=green] (0,0) circle (3cm);
}]
\draw (0,0) pic (3,3) {node0};
\end{tikzpicture}
我的树将比这大得多,它依赖于我在 Python 中找到的矩阵中的值。我还用不同的矩阵制作了很多不同的树,所以我希望找到一个通用的解决方案,并能够从我的 Python 矩阵中插入数字。因此,我认为使用节点要容易得多,这样我就可以将它们彼此相对放置(例如使用左侧和下方等)。
有人知道是否可以制作这样的节点吗?如果没有,您还有其他解决方案吗?
答案1
我建议如下:
- 用透明背景绘制节点;
- 之后,使用节点的坐标在背景层中填充节点。这就是想法,其中各种数字是“手动”设置的,但也许你可以找到一些好的方法从表中获取它们(查看
pgfplotstable
包)。使用正确的命名,你可以在foreach
循环中执行此操作。
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,calc,backgrounds}
\begin{document}
\begin{tikzpicture}[
treenodeT/.style={
circle, draw=black, align=center},
]
% draw the node with no background
\node[treenodeT] (N) {Loss0: 0.020 \\ Loss1: 0.100 \\ Loss2: 0.240};
% and after that...
\begin{scope}[on background layer]
\fill [green!20] let \p1 = ($(N.0)-(N.center)$) in
(N.center) -- (N.0) arc(0:20:{veclen(\x1,\y1)}) -- cycle;
\fill [orange!20] let \p1 = ($(N.0)-(N.center)$) in
(N.center) -- (N.20) arc(20:120:{veclen(\x1,\y1)}) -- cycle;
\fill [blue!20] let \p1 = ($(N.0)-(N.center)$) in
(N.center) -- (N.120) arc(120:360:{veclen(\x1,\y1)}) -- cycle;
\end{scope}
\end{tikzpicture}
\end{document}
“自动化”部门的最简单的想法可能是这样的,这很简单:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,calc,backgrounds}
\newcommand{\DoNode}[5][]{% (keys), name, loss1, loss2, loss3
\pgfmathtruncatemacro{\tmpa}{round(360*#3/(#3+#4+#5))}
\pgfmathtruncatemacro{\tmpb}{round(360*(#3+#4)/(#3+#4+#5))}
\node[treenodeT, #1] (#2) {Loss0: #3 \\ Loss1: #4 \\ Loss2: #5};
% and after that...
\begin{scope}[on background layer]
\fill [green!20] let \p1 = ($(#2.0)-(#2.center)$) in
(#2.center) -- (#2.0) arc(0:\tmpa:{veclen(\x1,\y1)}) -- cycle;
\fill [orange!20] let \p1 = ($(#2.0)-(#2.center)$) in
(#2.center) -- (#2.\tmpa) arc(\tmpa:\tmpb:{veclen(\x1,\y1)}) -- cycle;
\fill [blue!20] let \p1 = ($(#2.0)-(#2.center)$) in
(#2.center) -- (#2.\tmpb) arc(\tmpb:360:{veclen(\x1,\y1)}) -- cycle;
\end{scope}
}
\begin{document}
\begin{tikzpicture}[
treenodeT/.style={
circle, draw=black, align=center},
node distance=4cm,
]
\DoNode{N1}{0.020}{0.100}{0.240}
\DoNode[right of=N1]{N2}{0.010}{0.010}{0.020}
\end{tikzpicture}
\end{document}