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