3

I have the following dataset:

dataset = ["A": 5, "B": 10, "C": 25: "D" 3, ..., "Z": 36] 

I am trying to create a graph that looks like a mind map in which each data ("A", ..., "Z") in dataset is a child of a root node. Each child node should have a radius that is proportional to the number associated with the data. For example, the node for "A" (5 occurrences) would be smaller than the node for, e.g. "C" (25 occurrences).

The end would look something like this, except each node would be inside a circle and have different radius and color.

      A  D
      |  |
  B - Root - P
      |  |
      Q  E

I have tried the following code.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{mindmap,trees}
\usepackage{pgfmath,pgffor}
\usepackage[first=0, last=10]{lcg}

\begin{document}
\def\nodes{{"A","B","Q","C","D","E","F","J","H"}}%
\def\times{{31,14,6,29,16,48,9,1,26}}%
\pgfmathdeclarerandomlist{MyRandomColors}{%
   {red}%
   {red!25}%
   {magenta}%
 }%

 \newcommand{\random}{\rand\arabic{rand}}
 \pgfmathrandomitem{\RandomColor}{MyRandomColors} 
 \pagestyle{empty}
 \begin{tikzpicture}
 \path[mindmap, color=black,text=white]
 node[concept, minimum size=1087/10] {Root}
    [clockwise from=0]
    {child[concept color=\RandomColor] foreach \i in {0,...,8} { node[concept] { 
                 \pgfmathparse{\nodes[\i]}\pgfmathresult }}};

\end{tikzpicture}
\end{document} 

This code creates a graph with no more than 6 notes and always the same color. I have tried to set minimum size= in the nodes, but it does not work.

The current output is:

current image Any idea on how I can make that more than 6 nodes appear and that they have different sizes and colours? I would also very much appreciate solutions that look slightly different.

UPDATE

Now the graph holds as many nodes as necessary, but they all overlap each other. I am trying to modify the distance root-node to be a factor of the radius of the node. I want smaller nodes to be closer and bigger nodes to be further away. For that I need to access my array \times, but I can't figure out how.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{mindmap,trees}
\usepackage{pgfmath,pgffor}
\usepackage[first=0, last=10]{lcg}

\tikzset{get color/.code={\pgfmathparse{\LstColors[\i]}\xdef\mycolor{\pgfmathresult}}}

\begin{document}
\def\nodes{{"A","B","Q","C","D","E","F","J","H","G","M","N","O","P","Z","Q","R","T","V","W","Z"}}%
    \def\times{{31,14,6,29,16,48,9,1,26,10,11,12,13,45,15,200,17,18,19,56,87,70}}%
\def\allNodes{20}

 \newcommand{\random}{\rand\arabic{rand}}
 \pgfmathrandomitem{\RandomColor}{MyRandomColors} 
 \xdef\LstColors{"\RandomColor"}
 \foreach \X in {0,...,\allNodes}
 {\pgfmathrandomitem{\RandomColor}{MyRandomColors}
 \xdef\LstColors{\LstColors,"\RandomColor"}}
 \xdef\LstColors{{\LstColors}}
 \pagestyle{empty}
 \begin{tikzpicture}
 \path[
    mindmap, 
    color=black,
    text=white,
    level 1 concept/.append style={sibling angle=360/\allNodes},
    % attempt to change distance for all links - compiles, but does not work
    level 1 concept/.append style={sibling distance=200}]
 node[concept] (root) {Root}
    [clockwise from=0]
    {child foreach \i in {0,...,\allNodes} { [get color=\i]

    % minimum size=\pgfmathparse{\times[\i]}\pgfmathresult is attempt to change the size of node.
    node[concept,concept color=\mycolor, minimum size=\pgfmathparse{\times[\i]}\pgfmathresult] (child-\i) { 
                 \pgfmathparse{\nodes[\i]}\pgfmathresult }}};
\foreach \i in {0,...,\allCountries} {
     \draw[get color=\i]  (root) to[circle connection bar switch color=from
    (black) to (\mycolor), distance=\pgfmathparse{\times[\i]}\pgfmathresult] (child-\i);}

 % distance=\pgfmathparse{\times[\i]}\pgfmathresult is attempt to change distance of link node-wise.
\end{tikzpicture}
\end{document} 
  • Welcome to TeX.SE! You are setting the random color once and for all, which is why it is always the same. – user121799 Aug 23 '18 at 17:23
  • I tried already with node[concept color=\RandomColor] but it did not work in the loop – regina_fallangi Aug 23 '18 at 17:24
  • I am sorry, not really online now, but iff you add level 1 concept/.append style={sibling angle=360/9} to the path you should get all 9 nodes. And I guess \pgfmathparse{\countries[\i]}\pgfmathresult } should be \pgfmathparse{\nodes[\i]}\pgfmathresult }, or you define the \countries array. – user121799 Aug 23 '18 at 20:25
  • Sorry, the updated document is not a complete MWE. Please ping me again once it starts with \documentclass and ends with \end{document}. I am not very good at patching these fragments together. – user121799 Aug 24 '18 at 15:31
  • I added a response in my answer. Please refrain from editing my answer. – user121799 Aug 24 '18 at 15:49
3

I think this is one of the ugliest answers I have given in the recent time. Why is it ugly? I was unable to do everything in one foreach loop. (I'll be happy to explain more if needed.) Most likely I am missing something obvious. If not, then there might be some issue with mindmaps. Anyway, here comes my workaround. As already mentioned in my comments, you set the color once and for all, and it gets applied to all children in the same way. And you can increase the number of children by adjusting the silbling angle. Let's not talk about the rest. ;-)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{mindmap,trees}
\usepackage{pgfmath,pgffor}
\usepackage[first=0, last=10]{lcg}

\tikzset{get color/.code={\pgfmathparse{\LstColors[#1]}\xdef\mycolor{\pgfmathresult}}}
\begin{document}
\def\nodes{{"A","B","Q","C","D","E","F","J","H"}}%
\def\times{{31,14,6,29,16,48,9,1,26}}%
\pgfmathdeclarerandomlist{MyRandomColors}{%
   {red}%
   {red!25}%
   {magenta}%
 }%

 \newcommand{\random}{\rand\arabic{rand}}
 \pgfmathrandomitem{\RandomColor}{MyRandomColors} 
 \xdef\LstColors{"\RandomColor"}
 \foreach \X in {1,...,8}
 {\pgfmathrandomitem{\RandomColor}{MyRandomColors}
 \xdef\LstColors{\LstColors,"\RandomColor"}}
 \xdef\LstColors{{\LstColors}}
 \pagestyle{empty}
 \begin{tikzpicture}
 \path[mindmap, color=black,text=white,level 1 concept/.append style={sibling angle=360/9}]
 node[concept, minimum size=1087/10] (root) {Serbia}
    [clockwise from=0]
    {child foreach \i in {0,...,8} { [get color=\i]
    node[concept,concept color=\mycolor] (child-\i) { 
                 \pgfmathparse{\nodes[\i]}\pgfmathresult }}};
\foreach \i in {0,...,8} {
     \draw[get color=\i]  (root) to[circle connection bar switch color=from
    (black) to (\mycolor)] (child-\i);}
\end{tikzpicture}
\end{document} 

enter image description here

And please do me a favor: what the result on acroread. Other viewers may show gaps where acroread does not show them. (However, this is not my fault, the complicated mess above is. ;-)

INTERMEDIATE UPDATE: I made your code run. Note that you cannot put \pgfmathparse into some options. That't the reason why I used the get color code above. You can do the same for sizes.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{mindmap,trees}
\usepackage{pgfmath,pgffor}
\usepackage[first=0, last=10]{lcg}

\tikzset{get color/.code={\pgfmathparse{\LstColors[#1]}\xdef\mycolor{\pgfmathresult}},
get size/.code={\pgfmathparse{\times[#1]}\xdef\mysize{\pgfmathresult}}}
\begin{document}
\def\nodes{{"A","B","Q","C","D","E","F","J","H","G","M","N","O","P","Z","Q","R","T","V","W","Z"}}%
\def\times{{31,14,6,29,16,48,9,1,26,10,11,12,13,45,15,200,17,18,19,56,87,70}}%
\pgfmathdeclarerandomlist{MyRandomColors}{%
   {red}%
   {red!25}%
   {magenta}%
 }%
\def\allNodes{20}

 \newcommand{\random}{\rand\arabic{rand}}
 \pgfmathrandomitem{\RandomColor}{MyRandomColors} 
 \xdef\LstColors{"\RandomColor"}
 \foreach \X in {0,...,\allNodes}
 {\pgfmathrandomitem{\RandomColor}{MyRandomColors}
 \xdef\LstColors{\LstColors,"\RandomColor"}}
 \xdef\LstColors{{\LstColors}}
 \pagestyle{empty}
 \begin{tikzpicture}
 \path[
    mindmap, 
    color=black,
    text=white,
    level 1 concept/.append style={sibling angle=360/\allNodes},
    % attempt to change distance for all links - compiles, but does not work
    level 1 concept/.append style={sibling distance=200}]
 node[concept] (root) {Root}
    [clockwise from=0]
    {child foreach \i in {0,...,\allNodes} { [get color=\i,get size=\i]
    % minimum size=\pgfmathparse{\times[\i]}\pgfmathresult is attempt to change the size of node.
    node[concept,concept color=\mycolor, 
    scale={sqrt(\mysize/100)}] (child-\i) { 
                 \pgfmathparse{\nodes[\i]}\pgfmathresult }}};
\foreach \i in {0,...,\allNodes} {
     \draw[get color=\i,get size=\i]  (root) to[circle connection bar switch color=from
    (black) to (\mycolor)] (child-\i);}

 % distance=\pgfmathparse{\times[\i]}\pgfmathresult is attempt to change distance of link node-wise.
\end{tikzpicture}
\end{document}

enter image description here

This is definitely one of the ugliest mindmaps I have ever seen. Could one improve it? Quite possible. However, given all the additional information you gave me I am not sure you want to do a mindmap. Rather, I think you would be far better off if you use some graph drawing algorithm (which I am unfortunately not familiar with) to place the nodes and then use the the circle connection bar switch color magic to connect the nodes. Otherwise the whole enterprise will just make you have to reinvent all the things that have already been done in the context of graph drawing.

| improve this answer | |
  • First, thank you for this answer. Two follow-up questions: is it not possible to assign different sizes using the numbers in \times, or did you not see that part of the question? Second: is there a way to influence the length of the link root-node? I have 64 nodes and, while it's possible to create them all with your answer, now they are all at the top of each other and nothing is readable. – regina_fallangi Aug 24 '18 at 6:05
  • It looks like the answer is related to set angles for level/.list={1}, for I am really having problems with where to put it (either in tikzset or path, it does not compile anymore). I highly appreciate your help here. – regina_fallangi Aug 24 '18 at 6:19
  • 1
    @regina_fallangi I'm sorry, I do not fully understand your requests. Yes, you can change the distance of the children e.g. with level 2 concept/.append style={sibling distance=90}, of course adjust level and distance. Then set angles for level seems not to be something that can be found in the pgfmanual. Please add the definition and what you tried to your question, and I will look at it tomorrow. (Need to go hibernating now.) The length of the list looks suspicious, though. (And you know already how to use an array, did you try to do this for the angles?) – user121799 Aug 24 '18 at 6:34
  • Thanks! Believe me, I have tried. There is only something fundamental that I don't seem to understand about the syntax here, because it never compiles. I have tried with path[mindmap, level 2 concept/.append style={sibling distance=90} and with the same, but level 1 and nothing changes. Also, do you know if it is possible to change the radius of the circles? – regina_fallangi Aug 24 '18 at 14:29
  • 1
    Off-topic: even if you made ugly code you always will get +1 for me. I vote for the will you have to answer. :) – manooooh Aug 24 '18 at 15:31

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.