1

I am analyzing some data from a system that can have some binary configurations. I thought that a good strategy would be to visualize the output as a radial plot and overlay its binary configuration like sectors, as can be seen in the image.

enter image description here

My problem is the following I'm trying to automatize the part of plotting the colored sectors. Is there any package TikZ package that would simplify my life? Is there any package that allowing to transform a number (in this case 1..7) into binary and then examine the binary string to color the sectors accordingly ?

I thought that in the examples website I would find some binary encoding to generate patterns such as the ones used to generate optic encoders like those in the figure, but I did not. There's though a dardboard, but the problem is different the coloring is done manually. enter image description here

8

Edit: I slightly (or greatly) misunderstood the OP's requirements. The original answer is at the bottom.

This answer requires the latest CVS version of PGF for the new math library. Note that as this hasn't formed part of an official release it may (but is unlikely to) change.

\documentclass[border=0.5cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\renewcommand{\familydefault}{\sfdefault}
\begin{document}

\begin{tikzpicture}
\tikzmath{
    int \nbits, \p, \q, \N, \n;
    \nbits = 3;
    \p = 2^\nbits;
    \s = (360/\p);
    \r = 1;
    \t = 0.5;
    for \N in {0,...,\p-1}{ 
        \n = \N;
        {
            \node [font=\tiny, anchor=\N*\s+\s/2] at (\N*\s+\s/2:\r) {\N};
        };
        for \i in {0, ..., \nbits-1}{
            \q = 2^(\nbits-\i-1);
            if int(\n/\q) > 0 then {
                let \c = black;
                \n = \n - \q;
            } else {
                let \c = white;
            };
            \R = \r + \t*(\nbits- \i - 1);
            \a = \N*\s;
            \b = \a + \s;
            {
                \path [fill=\c, draw=black!75, very thick] 
                    (\a:\R) arc (\a:\b:\R) -- (\b:\R+\t) arc (\b:\a:\R+\t) -- cycle;
            };
        };
    };
}
\end{tikzpicture}

\end{document}

enter image description here

Edit: The rest of this answer is is the initial (wrong) answer.

Everything could have been done using \pgfmathparse and \foreach, but the math library aims to make multiple assignments a bit more clean. Also this answer does not cover adding the radial plot on top. More generic solutions (e.g., using pgfplots) are hopefully possible.

\documentclass[border=0.5cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\renewcommand{\familydefault}{\sfdefault}
\begin{document}

\begin{tikzpicture}
\tikzmath{
    int \nbits, \n, \q;
    \nbits = 8;
    \s = (360/\nbits);
    \r1 = 1;
    \r2 = 1.5;
    \k = 0;
    for \n in {0,1,2,4,8,16,32,64,128,15,33,65,163,211,244,255}{
        \x = mod(\k, 4);
        \y = int(\k/4);
        \k = \k + 1;
        {
            \node at (\x*4,-\y*4) {\n};
        };
        for \i in {0, ..., \nbits-1}{
            \q = 2^(\nbits-\i-1);
            if int(\n/\q) > 0 then {
                let \c1 = black;
                let \c2 = white;
                \n = \n - \q;
            } else {
                let \c1 = white;
                let \c2 = black;
            };
            \a = \s * \i;
            \b = \a + \s;
            {
                \begin{scope}[shift={(\x*4,-\y*4)}]
                    \path [fill=\c1, draw=black!75, very thick] 
                        (\a:\r1) arc (\a:\b:\r1) -- (\b:\r2) arc (\b:\a:\r2) -- cycle;
                    \node [font=\tiny, text=\c2] at (\a+\s/2:\r1/2+\r2/2) {\q};
                \end{scope}
            };
        };
    };
}
\end{tikzpicture}

\end{document}

enter image description here

With some minor adjustments it is possible to get "dartboard" patterns:

\documentclass[border=0.5cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\renewcommand{\familydefault}{\sfdefault}
\begin{document}

\begin{tikzpicture}
\tikzmath{
    int \nbits, \n, \q;
    \nbits = 8;
    \s = (360/\nbits);
    \r1 = 2;
    \r2 = 2.5;
    for \n in {65,163,211,244,255}{ \k = 0;
        for \i in {0, ..., \nbits-1}{
            \q = 2^(\nbits-\i-1);
            if int(\n/\q) > 0 then {
                let \c1 = black;
                \n = \n - \q;
            } else {
                let \c1 = white;
            };
            \a = \s * \i;
            \b = \a + \s;
            {               
                    \path [fill=\c1, draw=black!75, very thick] 
                        (\a:\r1) arc (\a:\b:\r1) -- (\b:\r2) arc (\b:\a:\r2) -- cycle;
            };
        };
        \r1 = \r2;
        \r2 = \r2 + 0.5;
    };
    for \i in {0, ..., \nbits-1}{
        \a = (360/\nbits) * (\i);
        \q = 2^(\nbits-\i-1);
        {
            \node [font=\tiny] at (\a+\s/2:1.625) {\q};
        };
    };
}
\end{tikzpicture}

\end{document}

enter image description here

2

Here is a solution using \pgfmathparse , \foreach and bitset bitset package

\documentclass[tikz,convert]{standalone}
\usepackage{tikz}
\usepackage{bitset}


\begin{document}
\begin{tikzpicture}

\tikzset{
    % argumentss = {initialAngle, radiousOffset, sectorAngleSize, thickness}
    sect/.style args={#1:#2:#3:#4}{
    insert path={   +(#1:#2) arc (#1:{#1+#3}:#2)  
                 -- +({#1+#3}:#4) arc ({#1+#3}:#1:{#2+#4}) 
                 -- cycle     }
  }
}
\tikzset{activeSector/.style={very thin, fill=black!20}}
\tikzset{inactiveSector/.style={very thin}}


\def\numBits{3}
\def\initialRadious{2}
\def\sectorThickness{.5}
\pgfmathsetmacro{\numSectors}{(2^\numBits)-1}
\pgfmathsetmacro{\maxIdxNumBits}{\numBits-1}
\pgfmathsetmacro{\sectorSize}{360/\numSectors}


\foreach \x [count=\n] in {1,...,\numSectors}
{
    \pgfmathsetmacro{\currentAngle}{\sectorSize*\x}
    \bitsetSetDec{xInbin}{\x}
    \foreach \bitId in {0,...,\maxIdxNumBits}
    {
        \pgfmathsetmacro{\currentRadious}{\initialRadious+\sectorThickness*(\bitId-1)}
        \pgfmathparse{\bitsetGet{xInbin}{\bitId})}
        \ifnum\pgfmathresult>0      
                    \draw[activeSector] (0,0) [sect=\currentAngle:
                                                    \currentRadious:
                                                    \sectorSize:
                                                    \sectorThickness];
        \else
                    \draw[inactiveSector] (0,0) [sect=\currentAngle:
                                                    \currentRadious:
                                                    \sectorSize:
                                                    \sectorThickness];
        \fi
    }
}

\end{tikzpicture}
\end{document}

enter image description here

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.