3

"Sunburst Chart — also known as Ring Chart, Multi-level Pie Chart, and Radial Treemap — is typically used to visualize hierarchical data structures."

What I am looking for is not exactly the above, but a generalization of it.

I would like to create a simple plot for a paper.

It should be vector graphics and easy to create.

I would like to add text inside the components if possible.

There are at least two options here (see below). It would maybe also possible to express this as some kind of a 'swirl' if you know what I mean...

It would also be great if I could stress the overlaps of the components, i.e. by an exploding pie chart with overlaps.

enter image description here

1 Answer 1

6

I suppose this could be called an annular graph, rather like circular pedigree charts, out of which project this grew. This should get you started. The enclosing environment is onion and takes one argument, the thickness of the annuli (the star causes x-y axes to be drawn). The \annulus macro takes three mandatory arguments: the layer number (innermost is 0), the starting angle and the ending angle, angles being specified counterclockwise. There is also an optional argument at the beginning for a fill color, and at the end for text. A complete command might look like this:

\annulus[purple!20]{2}{165}{325}[more\\stuff] (see the code below).

Nothing very complicated here. The TikZ arc function does most of the work.

\documentclass{article}

\usepackage{xcolor}
\usepackage{xparse}
\usepackage{tikz}


\usetikzlibrary{calc,positioning}

%% |=====8><-----| %%

\newlength{\layerwd}
\newcounter{outermost}

%% |=====8><-----| %%

\NewDocumentEnvironment{onion}{sm}{%*= draw axes; #1: thickness of each annulus
    \begin{tikzpicture}
        \setlength{\layerwd}{#2}%
        \setcounter{outermost}{0}
        \IfBooleanT{#1}{%
            \draw[<->] (-4,0) -- (4,0);
            \draw[<->] (0,4) -- (0,-4);
        }
}{%
    \foreach \A in {0,...,\theoutermost}{\draw[thick] (0,0) circle (\A*\layerwd+\layerwd);}
    \end{tikzpicture}
}

% *=unused; [optional fill color]; #3 layer; #4 start angle; #5 stop angle; #6 [optional text]
%% angles are counterclockwise in degrees
\NewDocumentCommand{\annulus}{sO{lightgray}mmmo}{%
    \filldraw[thick,fill=#2] (#4:#3*\layerwd) %% start here
        arc [radius=#3*\layerwd, start angle=#4, delta angle=#5-#4] %% inner arc
        -- (#5:#3*\layerwd+\layerwd) %% move out
        arc [radius=#3*\layerwd+\layerwd, start angle=#5, delta angle=#4-#5] %% outer arc
        -- cycle; %% Back to the beginnning
    \pgfmathsetmacro{\tmp}{(#5-#4)/2 +#4} %% Locate the middle of the arc
    \IfNoValueF{#6}{\node[inner sep=0pt, %%% If there is text, print it
        text width=#3*\layerwd*3+\layerwd,
        align=center,
        rotate=\tmp-90,
        font=\footnotesize] at (\tmp:#3*\layerwd+0.5*\layerwd)
        {#6}; %% Options text, rotated, in the middle of the arc
    }%
    \ifnum\theoutermost<#3\setcounter{outermost}{#3}\fi
}

%% |=====8><-----| %%

\begin{document}

\begin{onion}*{0.25in}
    \annulus{0}{0}{90}[1]
    \annulus{0}{90}{180}[2]
    \annulus{0}{180}{270}[3]
    \annulus{0}{270}{360}[4]
    \annulus[yellow]{1}{0}{120}[Y]
    \annulus[red!20]{4}{0}{90}
    \annulus[blue!30]{3}{60}{180}
    \annulus[cyan!20]{2}{45}{130}
    \annulus[purple!20]{2}{165}{325}[more\\stuff]
\end{onion}

\end{document}

annular graph

Update

It seemed odd to create an annular chart and not take advantage of TikZ's ability to put text on a path. The only change is that the \annulus macro can take an optional * to place the optional text on a circular path. Note that the text on a path cannot have line breaks; \\ will cause TeX to hang -- I have guarded against the possibility to a limited extent.

\documentclass{article}

\usepackage{xcolor}
\usepackage{xparse}
\usepackage{tikz}


\usetikzlibrary{calc,positioning}
\usetikzlibrary{decorations, decorations.text}

%% |=====8><-----| %%

\newlength{\layerwd}
\newcounter{outermost}

%% |=====8><-----| %%

\NewDocumentEnvironment{onion}{sm}{%*= draw axes; #1: thickness of each annulus
    \begin{tikzpicture}
        \setlength{\layerwd}{#2}%
        \setcounter{outermost}{0}
        \IfBooleanT{#1}{%
            \draw[<->] (-4,0) -- (4,0);
            \draw[<->] (0,4) -- (0,-4);
        }
}{%
    \foreach \A in {0,...,\theoutermost}{\draw[thick] (0,0) circle (\A*\layerwd+\layerwd);}
    \end{tikzpicture}
}

% *=text on a circular path; [optional fill color]; #3 layer;
% #4 start angle; #5 stop angle; #6 [optional text]
%% angles are counterclockwise in degrees
\NewDocumentCommand{\annulus}{sO{lightgray}mmmo}{%
    \filldraw[thick,fill=#2] (#4:#3*\layerwd) %% start here
        arc [radius=#3*\layerwd, start angle=#4, delta angle=#5-#4] %% inner arc
        -- (#5:#3*\layerwd+\layerwd) %% move out
        arc [radius=#3*\layerwd+\layerwd, start angle=#5, delta angle=#4-#5] %% outer arc
        -- cycle; %% Back to the beginnning
    \pgfmathsetmacro{\tmp}{(#5-#4)/2 +#4} %% Locate the middle of the arc
    \IfNoValueF{#6}{%
        \IfBooleanTF{#1}
        {%
            \begingroup
                \def\\{\space} %% A safety precaution, \\ = space on decorated text
                \path[rotate=\tmp-180,postaction={
                    decorate,
                    decoration={
                        text along path,
                        raise=-3pt,
                        text align={align=center},
                        reverse path=true,
                        text=#6
                    }
                }] (0,0) circle (#3*\layerwd+0.5*\layerwd);
            \endgroup
        }%% 
        {%
            \node[inner sep=0pt, %%% If there is text, print it
            text width=#3*\layerwd*3+\layerwd,
            align=center,
            rotate=\tmp-90,
            font=\footnotesize] at (\tmp:#3*\layerwd+0.5*\layerwd)
            {#6};
        }%
    }%
    \ifnum\theoutermost<#3\setcounter{outermost}{#3}\fi
}

%% |=====8><-----| %%

\begin{document}

\begin{onion}*{0.25in}
    \annulus{0}{0}{90}[1]
    \annulus{0}{90}{180}[2]
    \annulus{0}{180}{270}[3]
    \annulus{0}{270}{360}[4]
    \annulus*[yellow]{1}{0}{120}[Y is yellow]
    \annulus*[red!20]{4}{0}{90}[This is a bunch of bla bla]
    \annulus*[blue!30]{3}{60}{180}[This is some longer text]
    \annulus[cyan!20]{2}{45}{130}
    \annulus[purple!20]{2}{165}{325}[more\\stuff]
\end{onion}

\end{document}

annular graph with text on path

Update 2

Made a small change that ensures that text in the lower half of the graph is rightside-up.

\documentclass{article}

\usepackage{xcolor}
\usepackage{xparse}
\usepackage{tikz}


\usetikzlibrary{calc,positioning}
\usetikzlibrary{decorations, decorations.text}

%% |=====8><-----| %%

\newlength{\layerwd}
\newcounter{outermost}

%% |=====8><-----| %%

\NewDocumentEnvironment{onion}{sm}{%*= draw axes; #1: thickness of each annulus
    \begin{tikzpicture}
        \setlength{\layerwd}{#2}%
        \setcounter{outermost}{0}
        \IfBooleanT{#1}{%
            \draw[<->] (-4,0) -- (4,0);
            \draw[<->] (0,4) -- (0,-4);
        }%
}{%
    \foreach \A in {0,...,\theoutermost}{\draw[thick] (0,0) circle (\A*\layerwd+\layerwd);}
    \end{tikzpicture}
}

% *=text on a circular path; [optional fill color]; #3 layer;
% #4 start angle; #5 stop angle; #6 [optional text]
%% angles are counterclockwise in degrees
\NewDocumentCommand{\annulus}{sO{lightgray}mmmo}{%
    \filldraw[thick,fill=#2] (#4:#3*\layerwd) %% start here
        arc [radius=#3*\layerwd, start angle=#4, delta angle=#5-#4] %% inner arc
        -- (#5:#3*\layerwd+\layerwd) %% move out
        arc [radius=#3*\layerwd+\layerwd, start angle=#5, delta angle=#4-#5] %% outer arc
        -- cycle; %% Back to the beginnning
    \pgfmathsetmacro{\tmp}{(#5-#4)/2 +#4} %% Locate the middle of the arc
    \IfNoValueF{#6}{%
        \IfBooleanTF{#1}
        {%
            \begingroup
                %% text is always rightside-up:
                \pgfmathsetmacro{\rpTF}{ifthenelse(\tmp>180,"false","true")}
                \def\\{\space} %% A safety precaution, \\ = space on decorated text
                \path[rotate=\tmp-180,postaction={
                    decorate,
                    decoration={
                        text along path,
                        raise=-3pt,
                        text align={align=center},
                        reverse path=\rpTF,
                        text=#6
                    }
                }] (0,0) circle (#3*\layerwd+0.5*\layerwd);
            \endgroup
        }%% 
        {%
            \pgfmathsetmacro{\rpTF}{ifthenelse(\tmp>180,\tmp+90,\tmp-90)}
            \node[inner sep=0pt, %%% If there is text, print it
            text width=#3*\layerwd*3+\layerwd,
            align=center,
            rotate=\rpTF,
            font=\footnotesize] at (\tmp:#3*\layerwd+0.5*\layerwd)
            {#6};
        }%
    }%
    \ifnum\theoutermost<#3\setcounter{outermost}{#3}\fi
}

%% |=====8><-----| %%

\begin{document}

\begin{onion}*{0.3in}
    \annulus{0}{0}{90}[1]
    \annulus{0}{90}{180}[2]
    \annulus{0}{180}{270}[3]
    \annulus{0}{270}{360}[4]
    \annulus*[yellow]{1}{0}{120}[Y is yellow]
    \annulus*[red!20]{4}{0}{135}[This is a bunch of bla bla]
    \annulus*[blue!30]{3}{60}{180}[This is some longer text]
    \annulus[cyan!20]{2}{45}{130}
    \annulus[white]{3}{225}{315}[Line 1\\Line 2]
    \annulus*[purple!20]{2}{165}{325}[more\\stuff]
\end{onion}

\end{document}

revised annular graph

5
  • Awesome! I hope you did not spend too much time on this. Now I definitely will use your code. Thanks for the effort! Commented Nov 5, 2020 at 17:51
  • 1
    There's an update coming. Am away from my computer for a couple of hours..
    – sgmoye
    Commented Nov 5, 2020 at 17:54
  • Wow this is really useful and looks great. Hope others will be able to find this too! Let me know if you have suggestions for improving the title and thereby the likelihood of someone else reusing this... Commented Nov 6, 2020 at 7:39
  • Thanks. While I rather like "annular chart" or "annulus chart", it would appear that "multilevel pie chart" is also a possibility, according to visme.co/blog/types-of-graphs. I think the topics you've selected are fine. The "starburst chart" (same source) is also interesting...
    – sgmoye
    Commented Nov 6, 2020 at 10:27
  • I have also found that the term 'onion diagram' more often than not seems to refer to a series of circles superimposed on an encompassing larger circle; all of all the circles usually share a common line of coordinates, though occasionally a "multilevel pie chart" is also meant. Google "onion diagram" for examples.
    – sgmoye
    Commented Nov 6, 2020 at 11:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .