4

I'm making a tree of nodes, but i would like the nodes to be filled with different shapes, and I'm wondering if that's possible?

Right now my tree looks like this

enter image description here

But I would want to have each node like this

enter image description here

Where the sizes of the yellow, red and green fields are decided by the size of the loss.

The code that I currently have is this for the tree:

\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}

And the code for the node is this:

\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}

My tree is going to be a lot bigger than this, and it is dependent on values in a matrix that I've found in Python. I'm also making a lot of different trees from different matrices, so i hoped to find a general solution to this and be able to plug in the numbers from my python matrix. Therefore I'm thinking it is so much easier to use nodes so that I can place them realtive of each other (like use the left of and below of etc).

Does anyone know if it is possible to make nodes like this? If not, do you have any other solutions?

2

I propose the following:

  1. draw the nodes with transparent background;
  2. after that, fill the node in the background layer using the node's coordinates. This is the idea, where the various number are set "by hand" but probably you can find some nice way to get them from a table (look at pgfplotstable package). With the correct naming, you can do that in a foreach loop.
\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}

enter image description here

The simplest idea of "automate" the sectors could be this, which is quite straightforward:

\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}

enter image description here

1
  • Thank you very much, @Rmano ! This was useful :))
    – JohanneS
    Oct 12 '20 at 8:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.